From f81e919fbf7c91312e59969119610aa4d1533ef4 Mon Sep 17 00:00:00 2001 From: Damian Krzeminski Date: Fri, 3 Jan 2025 18:31:09 -0700 Subject: [PATCH] use connect et al. instead of Express --- app.js | 42 +++--- lib/routes/headers.js | 10 +- lib/routes/index.js | 60 ++++---- lib/routes/service-worker.js | 4 +- package.json | 7 +- pnpm-lock.yaml | 257 +++++++---------------------------- views/layout.jade | 2 +- 7 files changed, 116 insertions(+), 266 deletions(-) diff --git a/app.js b/app.js index 25241ec1..be419940 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,4 @@ -const express = require('express'); +const connect = require('@pirxpilot/connect'); const cachifyStatic = require('connect-cachify-static'); const gzip = require('connect-gzip-static'); const http = require('node:http'); @@ -9,24 +9,23 @@ const plugins = require('./lib/plugins'); const cookieParser = require('cookie-parser'); const logger = require('morgan'); const errorHandler = require('errorhandler'); +const renderer = require('connect-renderer'); -const app = module.exports = express(); +const app = module.exports = connect(); - -if (!process.env.SITE_URL) { - process.env.SITE_URL = app.get('env') === 'production' ? - 'https://liftie.info' : - 'http://localhost:3000'; -} +process.env.PORT ??= 3000; +process.env.SITE_URL ??= `http://localhost:${process.env.PORT}`; +process.env.NODE_ENV ??= 'development'; const root = path.join(__dirname, 'public'); const { SITE_URL: siteUrl, LIFTIE_STATIC_HOST: staticHost = '' } = process.env; + const cachify = cachifyStatic(root); -Object.assign(app.locals, { +app.locals = { min: '.min', decorateAbout() {}, siteUrl, @@ -35,25 +34,24 @@ Object.assign(app.locals, { og: { image: `${staticHost || siteUrl}/img/snowflake-512.png` } -}); -app.set('port', process.env.PORT || 3000); -app.set('views', `${__dirname}/views`); -app.engine('jade', require('@pirxpilot/jade-core').__express); -app.set('view engine', 'jade'); +}; + +app.use(renderer(`${__dirname}/views`).engine('jade', require('@pirxpilot/jade-core'))); app.use(logger('dev')); app.use(cookieParser()); app.use(cachify); -app.use((_req, res, next) => { - cachify.helpers().then(fns => { - res.locals.cachify = fns.cachify; - next(); - }); +app.use(async (req, res, next) => { + req.app = app; + res.locals ??= {}; + const fns = await cachify.helpers(); + res.locals.cachify = fns.cachify; + next(); }); app.use(gzip(root)); -if (app.get('env') === 'development') { +if (process.env.NODE_ENV === 'development') { app.locals.min = ''; app.use(errorHandler()); } @@ -78,8 +76,8 @@ app.run = function run() { process.exit(1); return; } - http.createServer(app).listen(app.get('port'), () => { - console.log(`Running on: http://localhost:${app.get('port')}`); + http.createServer(app).listen(process.env.PORT, () => { + console.log(`Running on: http://localhost:${process.env.PORT}`); }); }); }; diff --git a/lib/routes/headers.js b/lib/routes/headers.js index 25ffe7d7..e66bca29 100644 --- a/lib/routes/headers.js +++ b/lib/routes/headers.js @@ -37,20 +37,20 @@ const reportTo = JSON.stringify({ function csp(_req, res, next) { const cspNonce = crypto.randomBytes(16).toString('base64'); res.locals.cspNonce = cspNonce; - res.header(CSP_HEADER_NAME, cspPolicy.replace('$random', cspNonce)); + res.setHeader(CSP_HEADER_NAME, cspPolicy.replace('$random', cspNonce)); if (CSP_REPORT_URI) { - res.header('Report-To', reportTo); + res.setHeader('Report-To', reportTo); } next(); } function referrer(_req, res, next) { - res.header('Referrer-Policy', 'no-referrer-when-downgrade'); + res.setHeader('Referrer-Policy', 'no-referrer-when-downgrade'); next(); } function feature(_req, res, next) { - res.header('Feature-Policy', `fullscreen 'self'`); + res.setHeader('Feature-Policy', `fullscreen 'self'`); next(); } @@ -68,7 +68,7 @@ function link(_req, res, next) { } ].map(linkHeader); - res.header('Link', preloadLinks); + res.setHeader('Link', preloadLinks); next(); function linkHeader({ path, as, type }) { diff --git a/lib/routes/index.js b/lib/routes/index.js index a2581d51..3e98798b 100644 --- a/lib/routes/index.js +++ b/lib/routes/index.js @@ -3,6 +3,9 @@ const canonical = require('./canonical'); const plan = require('./plan'); const serviceWorker = require('./service-worker'); const headers = require('./headers'); +const Router = require('@pirxpilot/router'); +const parseurl = require('parseurl'); +const qs = require('qs'); module.exports = routes; @@ -142,11 +145,12 @@ function api(req, res, next) { return next(err); } if (resorts.length !== 1) { - return res.send(404, `Invalid resort name: ${req.params.resort}`); + return res.writeHead(404, `Invalid resort name: ${req.params.resort}`).end(); } // do not cache API responses - res.header('Cache-Control', 'no-cache, max-age=0, must-revalidate'); - res.send(resorts[0]); + res.setHeader('Cache-Control', 'no-cache, max-age=0, must-revalidate'); + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify(resorts[0])); }); } @@ -155,19 +159,21 @@ function meta(req, res, next) { if (err) { return next(err); } - res.header('Cache-Control', 'public, max-age=86400'); // good for 24hours - res.send(resorts); + res.setHeader('Cache-Control', 'public, max-age=86400'); // good for 24hours + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify(resorts)); }); } function routes(app) { + const router = new Router(); function reqData(req, _res, next) { req.data = app.data; next(); } - app.param('tag', (req, res, next, t) => { + router.param('tag', (req, res, next, t) => { const data = app.data; const tags = data.tags(); const requested = tags[t]?.members; @@ -175,9 +181,11 @@ function routes(app) { t = canonical(t); if (tags[t]) { // permanent redirect to canonical form of the tag - return res.redirect(301, `/tag/${t}`); + return res + .writeHead( 301, { location: `/tag/${encodeURIComponent(t)}` }) + .end(); } - return res.send(404, `Invalid tag name: ${req.params.tag}`); + return res.writeHead(404, `Invalid tag name: ${req.params.tag}`).end(); } req.requested = requested; req.tag = tags[t]; @@ -185,19 +193,25 @@ function routes(app) { next(); }); - app.get('/', reqData, headers, index, renderResorts); - app.get('/resort/:resort', reqData, headers, index, renderResorts); - app.get('/widget/resort/:resort', reqData, headers, widget, renderResorts); - app.get('/tag/:tag', reqData, headers, tag, renderResorts); - app.get('/stars', reqData, headers, stars, renderResorts); - app.get('/api/resort/:resort', reqData, api); - app.get('/api/meta', reqData, meta); - app.get('/sitemap.xml', reqData, sitemap); - app.get('/about', headers, about); - app.get('/absent', reqData, headers, absent, renderResorts); - app.get('/confused', reqData, headers, confused, renderResorts); - app.get('/closed', reqData, headers, closed, renderResorts); - app.get('/stats/:tag', reqData, headers, stats); - app.get('/stats', reqData, headers, stats); - app.get('/sw.js', serviceWorker); + router.use((req, _res, next) => { + req.query = qs.parse(parseurl(req).query); + next(); + }); + router.get('/', reqData, headers, index, renderResorts); + router.get('/resort/:resort', reqData, headers, index, renderResorts); + router.get('/widget/resort/:resort', reqData, headers, widget, renderResorts); + router.get('/tag/:tag', reqData, headers, tag, renderResorts); + router.get('/stars', reqData, headers, stars, renderResorts); + router.get('/api/resort/:resort', reqData, api); + router.get('/api/meta', reqData, meta); + router.get('/sitemap.xml', reqData, sitemap); + router.get('/about', headers, about); + router.get('/absent', reqData, headers, absent, renderResorts); + router.get('/confused', reqData, headers, confused, renderResorts); + router.get('/closed', reqData, headers, closed, renderResorts); + router.get('/stats/:tag', reqData, headers, stats); + router.get('/stats', reqData, headers, stats); + router.get('/sw.js', serviceWorker); + + app.use(router); } diff --git a/lib/routes/service-worker.js b/lib/routes/service-worker.js index 7e03a16f..5db54484 100644 --- a/lib/routes/service-worker.js +++ b/lib/routes/service-worker.js @@ -14,8 +14,8 @@ const DEBUG = NODE_ENV !== 'production'; function renderServiceWorker(_req, res) { createServiceWorkerScript(res.locals).then(serviceWorkerScript => { // do not cache service worker - res.header('Cache-Control', 'no-cache, max-age=0, must-revalidate'); - res.header('Content-Type', 'text/javascript'); + res.setHeader('Cache-Control', 'no-cache, max-age=0, must-revalidate'); + res.setHeader('Content-Type', 'text/javascript'); res.write(serviceWorkerScript); res.end(); }); diff --git a/package.json b/package.json index 4b72661c..68375dfe 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,14 @@ "test": "make lint test" }, "dependencies": { + "@pirxpilot/connect": "^4.0.2", "@pirxpilot/jade-core": "^1.12.1", "@pirxpilot/k": "^1.0.0", + "@pirxpilot/router": "^1.0.0", "@pirxpilot/swipe": "^2.0.2", "connect-cachify-static": "^4.0.0", "connect-gzip-static": "^4.0.0", + "connect-renderer": "^0.1.1", "cookie-parser": "^1.4.3", "css-select": "~5", "debounce": "^2.0.0", @@ -42,13 +45,13 @@ "el-component": "^1.0.1", "errorhandler": "^1.5.0", "esbuild": "^0.24.0", - "express": "^4.16.2", "htmlparser2": "~10", "js-cookie": "^3.0.5", "limiter": "~2.1.0", "lodash": "^4.16.6", "morgan": "^1.9.0", - "qs": "^6.3.0", + "parseurl": "^1.3.3", + "qs": "^6.13.1", "ro-rating": "^1.0.2", "superagent": "~10.1.0", "tiny-pager": "^1.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b952c1e1..d347fa17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,12 +11,18 @@ importers: .: dependencies: + '@pirxpilot/connect': + specifier: ^4.0.2 + version: 4.0.2 '@pirxpilot/jade-core': specifier: ^1.12.1 version: 1.12.2 '@pirxpilot/k': specifier: ^1.0.0 version: 1.0.1 + '@pirxpilot/router': + specifier: ^1.0.0 + version: 1.0.0 '@pirxpilot/swipe': specifier: ^2.0.2 version: 2.0.2 @@ -26,6 +32,9 @@ importers: connect-gzip-static: specifier: ^4.0.0 version: 4.2.0 + connect-renderer: + specifier: ^0.1.1 + version: 0.1.1 cookie-parser: specifier: ^1.4.3 version: 1.4.7 @@ -56,9 +65,6 @@ importers: esbuild: specifier: ^0.24.0 version: 0.24.2 - express: - specifier: ^4.16.2 - version: 4.21.2 htmlparser2: specifier: ~10 version: 10.0.0 @@ -74,8 +80,11 @@ importers: morgan: specifier: ^1.9.0 version: 1.10.0 + parseurl: + specifier: ^1.3.3 + version: 1.3.3 qs: - specifier: ^6.3.0 + specifier: ^6.13.1 version: 6.13.1 ro-rating: specifier: ^1.0.2 @@ -348,6 +357,9 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@pirxpilot/connect@4.0.2': + resolution: {integrity: sha512-GobsW2CE8hzz5Y4FqaQPdFvhF46SoiO3TAdXAtfCDxcLQpqVm+i2Jt4p+OPLBdRVKyHgvBJ7IQ1PkV8gspcVbA==} + '@pirxpilot/events@1.0.1': resolution: {integrity: sha512-Xy/trHRWfkeIAJQZlaJ8wDngGbyK4Q/oWQ32meC6sXBcT7QGu3t5EOz+7yjlFoMM3wX1HL4kSKxG+WQPgCnBWg==} @@ -360,6 +372,10 @@ packages: '@pirxpilot/replay@2.2.1': resolution: {integrity: sha512-h7ttPOELEOxxShD71csZoMmyd/moKg/BspRu2JmUS/18McYzZiiYm5E9y2FXGJ27dFSGKNzKuQjxYQCbUG2AIw==} + '@pirxpilot/router@1.0.0': + resolution: {integrity: sha512-6AgMB0U1h2qI8w5KAabgOAt0vdzp0E6naLt3sC3EMO5OQl4X0VvGHq+GqquBOM0ZsXuX3kke5xdqmuw9KDii3w==} + engines: {node: '>= 0.10'} + '@pirxpilot/swipe@2.0.2': resolution: {integrity: sha512-Gc01mbSQDh8RDWxpOMrRuklfww118OOBjrvX/Ik5gyzBCdJ22EU9IbHcO5bD1r3LC1ehSmTEnb1beEgEwkYEjg==} @@ -387,9 +403,6 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} @@ -416,20 +429,12 @@ packages: resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} engines: {node: '>= 0.8'} - body-parser@1.20.3: - resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - call-bind-apply-helpers@1.0.1: resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} engines: {node: '>= 0.4'} @@ -475,17 +480,12 @@ packages: resolution: {integrity: sha512-T6ErLEf3t15KVRcns/J5UWLL1OJT5gTD8QofYDRVGG8pEzE6uXWkkd8HgsZ224mwHtENv9kbpIdgi0liMjoLtw==} engines: {node: '>= 20.1.0'} + connect-renderer@0.1.1: + resolution: {integrity: sha512-pv67IgdHiJrRlfDFgEiCl7LQNdP2NHfT2Tts0wJXmh6Mjub2pJ3RRH/UV/uWyGImneCVyMvCi8NdBBhhdKerMw==} + constantinople@4.0.1: resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} - content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - cookie-parser@1.4.7: resolution: {integrity: sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==} engines: {node: '>= 0.8.0'} @@ -493,10 +493,6 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} - engines: {node: '>= 0.6'} - cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -629,10 +625,6 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - express@4.21.2: - resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} - engines: {node: '>= 0.10.0'} - eyes@0.1.8: resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} engines: {node: '> 0.1.90'} @@ -640,10 +632,6 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} - engines: {node: '>= 0.8'} - foreground-child@3.3.0: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} @@ -655,10 +643,6 @@ packages: formidable@3.5.2: resolution: {integrity: sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==} - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -700,17 +684,9 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -754,13 +730,6 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - merge-descriptors@1.0.3: - resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -847,8 +816,9 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@0.1.12: - resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -875,14 +845,6 @@ packages: resolution: {integrity: sha512-ZkaRWtaLBZl7KKAKndKYUL8WqNT+cQHKRZnT4RYYms48jQkFw3rrBL+/N5K/KtdEveHkxs982MX2BkDKub2ZMg==} engines: {node: '>= 6.0.0'} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} - engines: {node: '>=0.6'} - qs@6.13.1: resolution: {integrity: sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==} engines: {node: '>=0.6'} @@ -891,10 +853,6 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - read@1.0.7: resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} engines: {node: '>=0.8'} @@ -909,12 +867,6 @@ packages: safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} @@ -1029,22 +981,6 @@ packages: transform-property@0.0.1: resolution: {integrity: sha512-L0nMJCwu3/Lpd5t/pRQl+JoYU5V0sYubcn30yWZnHG0HjC6Gdr/Eg/bun1OixYPmsEZdA7Khbq2jiSIjzlEv6Q==} - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - void-elements@3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} @@ -1221,6 +1157,13 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@pirxpilot/connect@4.0.2': + dependencies: + debug: 4.4.0 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + '@pirxpilot/events@1.0.1': {} '@pirxpilot/jade-core@1.12.2': @@ -1244,6 +1187,12 @@ snapshots: transitivePeerDependencies: - supports-color + '@pirxpilot/router@1.0.0': + dependencies: + methods: 1.1.2 + parseurl: 1.3.3 + path-to-regexp: 8.2.0 + '@pirxpilot/swipe@2.0.2': dependencies: '@pirxpilot/events': 1.0.1 @@ -1268,8 +1217,6 @@ snapshots: ansi-styles@6.2.1: {} - array-flatten@1.1.1: {} - asap@2.0.6: {} assert-never@1.4.0: {} @@ -1292,31 +1239,12 @@ snapshots: dependencies: safe-buffer: 5.1.2 - body-parser@1.20.3: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 4.4.0 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.13.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - boolbase@1.0.0: {} brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 - bytes@3.1.2: {} - call-bind-apply-helpers@1.0.1: dependencies: es-errors: 1.3.0 @@ -1365,17 +1293,17 @@ snapshots: transitivePeerDependencies: - supports-color + connect-renderer@0.1.1: + dependencies: + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + constantinople@4.0.1: dependencies: '@babel/parser': 7.26.3 '@babel/types': 7.26.3 - content-disposition@0.5.4: - dependencies: - safe-buffer: 5.2.1 - - content-type@1.0.5: {} - cookie-parser@1.4.7: dependencies: cookie: 0.7.2 @@ -1383,8 +1311,6 @@ snapshots: cookie-signature@1.0.6: {} - cookie@0.7.1: {} - cookie@0.7.2: {} cookiejar@2.1.4: {} @@ -1515,58 +1441,10 @@ snapshots: etag@1.8.1: {} - express@4.21.2: - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.3 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.0.6 - debug: 4.4.0 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.3.1 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.3 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.12 - proxy-addr: 2.0.7 - qs: 6.13.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.19.0 - serve-static: 1.16.2 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - eyes@0.1.8: {} fast-safe-stringify@2.1.1: {} - finalhandler@1.3.1: - dependencies: - debug: 4.4.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - foreground-child@3.3.0: dependencies: cross-spawn: 7.0.6 @@ -1584,8 +1462,6 @@ snapshots: hexoid: 2.0.0 once: 1.4.0 - forwarded@0.2.0: {} - fresh@0.5.2: {} function-bind@1.1.2: {} @@ -1641,14 +1517,8 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - inherits@2.0.4: {} - ipaddr.js@1.9.1: {} - is-fullwidth-code-point@3.0.0: {} is-promise@2.2.2: {} @@ -1684,10 +1554,6 @@ snapshots: math-intrinsics@1.1.0: {} - media-typer@0.3.0: {} - - merge-descriptors@1.0.3: {} - methods@1.1.2: {} mime-db@1.52.0: {} @@ -1755,7 +1621,7 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@0.1.12: {} + path-to-regexp@8.2.0: {} picocolors@1.1.1: {} @@ -1790,28 +1656,12 @@ snapshots: revalidator: 0.1.8 winston: 2.4.7 - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - qs@6.13.0: - dependencies: - side-channel: 1.1.0 - qs@6.13.1: dependencies: side-channel: 1.1.0 range-parser@1.2.1: {} - raw-body@2.5.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - read@1.0.7: dependencies: mute-stream: 0.0.8 @@ -1822,10 +1672,6 @@ snapshots: safe-buffer@5.1.2: {} - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - sax@1.4.1: {} send@0.19.0: @@ -1994,17 +1840,6 @@ snapshots: transform-property@0.0.1: {} - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - unpipe@1.0.0: {} - - utils-merge@1.0.1: {} - - vary@1.1.2: {} - void-elements@3.1.0: {} which@2.0.2: diff --git a/views/layout.jade b/views/layout.jade index 29ccdea4..c6b228b9 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -57,7 +57,7 @@ html( link(rel='manifest', href='/manifest.json') +liftie-stylesheet('/stylesheets/style') link(rel='publisher', href='https://plus.google.com/107555641794612264233') - body(data-ga-property-id=settings.gaPropertyId) + body() block content block footer footer