@tinyhttp/app
Advanced tools
Comparing version 0.1.17 to 0.1.20
@@ -1,268 +0,1 @@ | ||
import { createServer } from 'http'; | ||
import rg from 'regexparam'; | ||
import { parse } from 'url'; | ||
import proxyAddr from 'proxy-addr'; | ||
import parseRange from 'range-parser'; | ||
import { format, parse as parse$1 } from 'content-type'; | ||
import etag from '@tinyhttp/etag'; | ||
const getQueryParams = (url = '/') => { | ||
return parse(url, true).query; | ||
}; | ||
const exec = (path, result) => { | ||
let i = 0, out = {}; | ||
let matches = result.pattern.exec(path); | ||
while (i < result.keys.length) { | ||
out[result.keys[i]] = matches?.[++i] || null; | ||
} | ||
return out; | ||
}; | ||
const getURLParams = (reqUrl = '/', url = '/') => { | ||
return exec(reqUrl, rg(url)); | ||
}; | ||
const getRouteFromApp = (app, handler) => { | ||
return app.routes.find(h => h.handler.name === handler.name); | ||
}; | ||
const compileTrust = (val) => { | ||
if (typeof val === 'function') | ||
return val; | ||
if (val === true) { | ||
// Support plain true/false | ||
return function () { | ||
return true; | ||
}; | ||
} | ||
if (typeof val === 'number') { | ||
// Support trusting hop count | ||
return (_, i) => { | ||
if (val) { | ||
return i < val; | ||
} | ||
}; | ||
} | ||
if (typeof val === 'string') { | ||
// Support comma-separated values | ||
val = val.split(/ *, */); | ||
} | ||
return proxyAddr.compile(val || []); | ||
}; | ||
const getProtocol = (req) => { | ||
const proto = req.connection.encrypted ? 'https' : 'http'; | ||
if (!compileTrust(req.connection.remoteAddress)) { | ||
return proto; | ||
} | ||
const header = req.headers['X-Forwarded-Proto'] || proto; | ||
const index = header.indexOf(','); | ||
return index !== -1 ? header.substring(0, index).trim() : header.trim(); | ||
}; | ||
const getHeader = (req) => (header) => { | ||
return req.headers[header.toLowerCase()]; | ||
}; | ||
const getRangeFromHeader = (req) => (size, options) => { | ||
const range = req.get('Range'); | ||
if (!range) | ||
return; | ||
return parseRange(size, range, options); | ||
}; | ||
const checkIfXMLHttpRequest = (req) => { | ||
if (req.headers['X-Requested-With'] === 'XMLHttpRequest') { | ||
return true; | ||
} | ||
else { | ||
return false; | ||
} | ||
}; | ||
const getHostname = (req) => { | ||
let host = req.get('X-Forwarded-Host'); | ||
if (!host || !compileTrust(req.connection.remoteAddress)) { | ||
host = req.get('Host'); | ||
} | ||
if (!host) | ||
return; | ||
// IPv6 literal support | ||
var offset = host[0] === '[' ? host.indexOf(']') + 1 : 0; | ||
var index = host.indexOf(':', offset); | ||
return index !== -1 ? host.substring(0, index) : host; | ||
}; | ||
const getIP = (req) => { | ||
return proxyAddr(req, compileTrust); | ||
}; | ||
const createETag = (body, encoding) => { | ||
const buf = !Buffer.isBuffer(body) ? Buffer.from(body, encoding) : body; | ||
return etag(buf, { weak: true }); | ||
}; | ||
function setCharset(type, charset) { | ||
const parsed = parse$1(type); | ||
parsed.parameters.charset = charset; | ||
return format(parsed); | ||
} | ||
const json = (_, res) => (body, ...args) => { | ||
res.setHeader('Content-Type', 'application/json'); | ||
if (typeof body === 'object' && body != 'null') { | ||
res.end(JSON.stringify(body, null, 2), ...args); | ||
} | ||
else if (typeof body === 'string') { | ||
res.end(body, ...args); | ||
} | ||
return res; | ||
}; | ||
const send = (req, res) => (body) => { | ||
let bodyToSend = body; | ||
// in case of object - turn it to json | ||
if (typeof body === 'object' && body !== 'null') { | ||
bodyToSend = JSON.stringify(body, null, 2); | ||
} | ||
else { | ||
if (typeof body === 'string') { | ||
// reflect this in content-type | ||
const type = res.getHeader('Content-Type'); | ||
if (typeof type === 'string') { | ||
res.setHeader('Content-Type', setCharset(type, 'utf-8')); | ||
} | ||
} | ||
} | ||
// Set encoding | ||
let encoding = 'utf8'; | ||
// populate ETag | ||
let etag; | ||
if (!res.getHeader('etag') && (etag = createETag(bodyToSend, encoding))) { | ||
res.setHeader('etag', etag); | ||
} | ||
// strip irrelevant headers | ||
if (res.statusCode === 204 || res.statusCode === 304) { | ||
res.removeHeader('Content-Type'); | ||
res.removeHeader('Content-Length'); | ||
res.removeHeader('Transfer-Encoding'); | ||
bodyToSend = ''; | ||
} | ||
if (req.method === 'HEAD') { | ||
res.end(''); | ||
} | ||
if (typeof body === 'object') { | ||
if (body === null) { | ||
res.end(''); | ||
} | ||
else if (Buffer.isBuffer(body)) { | ||
if (!res.getHeader('Content-Type')) { | ||
res.setHeader('content-type', 'application/octet-stream'); | ||
} | ||
} | ||
else { | ||
json(req, res)(bodyToSend, encoding) ; | ||
} | ||
} | ||
else { | ||
{ | ||
// respond with encoding | ||
res.end(bodyToSend, encoding); | ||
} | ||
} | ||
return res; | ||
}; | ||
const status = (_, res) => (status) => { | ||
res.statusCode = status; | ||
return res; | ||
}; | ||
const notFound = () => (_, res) => { | ||
if (!res.writableEnded) { | ||
res.statusCode = 404; | ||
res.end('Not found'); | ||
} | ||
}; | ||
const METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'HEAD']; | ||
const createHandler = ({ url, handler, method }) => ({ | ||
method, | ||
handler: handler || url, | ||
url: typeof url === 'string' ? url : '*' | ||
}); | ||
class App { | ||
constructor() { | ||
this.routes = []; | ||
this.middleware = []; | ||
} | ||
get(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'GET' })); | ||
return this; | ||
} | ||
post(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'POST' })); | ||
return this; | ||
} | ||
put(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'PUT' })); | ||
return this; | ||
} | ||
patch(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'PATCH' })); | ||
return this; | ||
} | ||
head(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'HEAD' })); | ||
return this; | ||
} | ||
all(url, handler) { | ||
for (const method of METHODS) { | ||
this.routes.push(createHandler({ url, handler, method })); | ||
} | ||
return this; | ||
} | ||
use(handler) { | ||
this.middleware.push({ | ||
handler | ||
}); | ||
return this; | ||
} | ||
listen(port, cb = () => console.log(`Started on http://${host}:${port}`), host = 'localhost', backlog) { | ||
// @ts-ignore | ||
const server = createServer((req, res) => { | ||
/// Define extensions | ||
/* | ||
Request extensions | ||
*/ | ||
const proto = getProtocol(req); | ||
const secure = proto === 'https'; | ||
req.protocol = proto; | ||
req.secure = secure; | ||
req.connection = Object.assign(req.socket, { | ||
encrypted: secure | ||
}); | ||
req.query = getQueryParams(req.url); | ||
req.get = getHeader(req); | ||
req.range = getRangeFromHeader(req); | ||
req.xhr = checkIfXMLHttpRequest(req); | ||
req.hostname = getHostname(req); | ||
/* | ||
Response extensions | ||
*/ | ||
res.send = send(req, res); | ||
res.json = json(req, res); | ||
res.status = status(req, res); | ||
this.routes.map(({ url, method, handler }) => { | ||
if (req.method === method) { | ||
if (url && req.url && rg(url).pattern.test(req.url)) { | ||
req.params = getURLParams(req.url, url); | ||
req.route = getRouteFromApp(this, handler); | ||
if (!res.writableEnded) { | ||
res.statusCode = 200; | ||
handler(req, res); | ||
} | ||
} | ||
} | ||
}); | ||
let middleware = this.middleware.filter(m => m.handler.name !== 'logger'); | ||
middleware.push({ handler: notFound() }); | ||
const logger = this.middleware.find(m => m.handler.name === 'logger'); | ||
if (logger) | ||
middleware.push(logger); | ||
middleware.map(({ handler }) => { | ||
handler(req, res); | ||
}); | ||
}); | ||
return server.listen(port, host, backlog, cb); | ||
} | ||
} | ||
export { App, METHODS, checkIfXMLHttpRequest, compileTrust, getHeader, getHostname, getIP, getProtocol, getQueryParams, getRangeFromHeader, getRouteFromApp, getURLParams, json, notFound, send, status }; | ||
import{createServer as e}from"http";import t from"regexparam";import{parse as r}from"url";import n from"proxy-addr";import o from"range-parser";import{format as s,parse as d}from"content-type";import u from"@tinyhttp/etag";const a=(e="/")=>r(e,!0).query,i=(e="/",r="/")=>((e,t)=>{let r=0,n={},o=t.pattern.exec(e);for(;r<t.keys.length;)n[t.keys[r]]=(null==o?void 0:o[++r])||null;return n})(e,t(r)),l=(e,t)=>e.routes.find(e=>e.handler.name===t.name),h=e=>"function"==typeof e?e:!0===e?function(){return!0}:"number"==typeof e?(t,r)=>{if(e)return r<e}:("string"==typeof e&&(e=e.split(/ *, */)),n.compile(e||[])),p=e=>{const t=e.connection.encrypted?"https":"http";if(!h(e.connection.remoteAddress))return t;const r=e.headers["X-Forwarded-Proto"]||t,n=r.indexOf(",");return-1!==n?r.substring(0,n).trim():r.trim()},f=e=>t=>e.headers[t.toLowerCase()],m=e=>(t,r)=>{const n=e.get("Range");if(n)return o(t,n,r)},c=e=>"XMLHttpRequest"===e.headers["X-Requested-With"],g=e=>{let t=e.get("X-Forwarded-Host");if(t&&h(e.connection.remoteAddress)||(t=e.get("Host")),t){var r="["===t[0]?t.indexOf("]")+1:0,n=t.indexOf(":",r);return-1!==n?t.substring(0,n):t}},y=e=>n(e,h),H=(e,t)=>{const r=Buffer.isBuffer(e)?e:Buffer.from(e,t);return u(r,{weak:!0})};const C=(e,t)=>(e,...r)=>(t.setHeader("Content-Type","application/json"),"object"==typeof e&&"null"!=e?t.end(JSON.stringify(e,null,2),...r):"string"==typeof e&&t.end(e,...r),t),T=(e,t)=>r=>{let n=r;if("object"==typeof r&&"null"!==r)n=JSON.stringify(r,null,2);else if("string"==typeof r){const e=t.getHeader("Content-Type");"string"==typeof e&&t.setHeader("Content-Type",function(e,t){const r=d(e);return r.parameters.charset=t,s(r)}(e,"utf-8"))}let o;return!t.getHeader("etag")&&(o=H(n,"utf8"))&&t.setHeader("etag",o),204!==t.statusCode&&304!==t.statusCode||(t.removeHeader("Content-Type"),t.removeHeader("Content-Length"),t.removeHeader("Transfer-Encoding"),n=""),"HEAD"===e.method&&t.end(""),"object"==typeof r?null===r?t.end(""):Buffer.isBuffer(r)?t.getHeader("Content-Type")||t.setHeader("content-type","application/octet-stream"):C(0,t)(n,"utf8"):t.end(n,"utf8"),t},w=(e,t)=>e=>(t.statusCode=e,t),b=()=>(e,t)=>{t.writableEnded||(t.statusCode=404,t.end("Not found"))},E=["GET","POST","PUT","PATCH","HEAD"],x=({url:e,handler:t,method:r})=>({method:r,handler:t||e,url:"string"==typeof e?e:"*"});class O{constructor(){this.routes=[],this.middleware=[]}get(e,t){return this.routes.push(x({url:e,handler:t,method:"GET"})),this}post(e,t){return this.routes.push(x({url:e,handler:t,method:"POST"})),this}put(e,t){return this.routes.push(x({url:e,handler:t,method:"PUT"})),this}patch(e,t){return this.routes.push(x({url:e,handler:t,method:"PATCH"})),this}head(e,t){return this.routes.push(x({url:e,handler:t,method:"HEAD"})),this}all(e,t){for(const r of E)this.routes.push(x({url:e,handler:t,method:r}));return this}use(e){return this.middleware.push({handler:e}),this}listen(r,n=(()=>console.log(`Started on http://${o}:${r}`)),o="localhost",s){return e((e,r)=>{const n=p(e),o="https"===n;e.protocol=n,e.secure=o,e.connection=Object.assign(e.socket,{encrypted:o}),e.query=a(e.url),e.get=f(e),e.range=m(e),e.xhr=c(e),e.hostname=g(e),r.send=T(e,r),r.json=C(0,r),r.status=w(0,r),this.routes.map(({url:n,method:o,handler:s})=>{e.method===o&&n&&e.url&&t(n).pattern.test(e.url)&&(e.params=i(e.url,n),e.route=l(this,s),r.writableEnded||(r.statusCode=200,s(e,r)))});let s=this.middleware.filter(e=>"logger"!==e.handler.name);s.push({handler:(e,t)=>{t.writableEnded||(t.statusCode=404,t.end("Not found"))}});const d=this.middleware.find(e=>"logger"===e.handler.name);d&&s.push(d),s.map(({handler:t})=>{t(e,r)})}).listen(r,o,s,n)}}export{O as App,E as METHODS,c as checkIfXMLHttpRequest,h as compileTrust,f as getHeader,g as getHostname,y as getIP,p as getProtocol,a as getQueryParams,m as getRangeFromHeader,l as getRouteFromApp,i as getURLParams,C as json,b as notFound,T as send,w as status}; |
@@ -1,289 +0,1 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var http = require('http'); | ||
var rg = _interopDefault(require('regexparam')); | ||
var url = require('url'); | ||
var proxyAddr = _interopDefault(require('proxy-addr')); | ||
var parseRange = _interopDefault(require('range-parser')); | ||
var contentType = require('content-type'); | ||
var etag = _interopDefault(require('@tinyhttp/etag')); | ||
const getQueryParams = (url$1 = '/') => { | ||
return url.parse(url$1, true).query; | ||
}; | ||
const exec = (path, result) => { | ||
let i = 0, out = {}; | ||
let matches = result.pattern.exec(path); | ||
while (i < result.keys.length) { | ||
out[result.keys[i]] = matches?.[++i] || null; | ||
} | ||
return out; | ||
}; | ||
const getURLParams = (reqUrl = '/', url = '/') => { | ||
return exec(reqUrl, rg(url)); | ||
}; | ||
const getRouteFromApp = (app, handler) => { | ||
return app.routes.find(h => h.handler.name === handler.name); | ||
}; | ||
const compileTrust = (val) => { | ||
if (typeof val === 'function') | ||
return val; | ||
if (val === true) { | ||
// Support plain true/false | ||
return function () { | ||
return true; | ||
}; | ||
} | ||
if (typeof val === 'number') { | ||
// Support trusting hop count | ||
return (_, i) => { | ||
if (val) { | ||
return i < val; | ||
} | ||
}; | ||
} | ||
if (typeof val === 'string') { | ||
// Support comma-separated values | ||
val = val.split(/ *, */); | ||
} | ||
return proxyAddr.compile(val || []); | ||
}; | ||
const getProtocol = (req) => { | ||
const proto = req.connection.encrypted ? 'https' : 'http'; | ||
if (!compileTrust(req.connection.remoteAddress)) { | ||
return proto; | ||
} | ||
const header = req.headers['X-Forwarded-Proto'] || proto; | ||
const index = header.indexOf(','); | ||
return index !== -1 ? header.substring(0, index).trim() : header.trim(); | ||
}; | ||
const getHeader = (req) => (header) => { | ||
return req.headers[header.toLowerCase()]; | ||
}; | ||
const getRangeFromHeader = (req) => (size, options) => { | ||
const range = req.get('Range'); | ||
if (!range) | ||
return; | ||
return parseRange(size, range, options); | ||
}; | ||
const checkIfXMLHttpRequest = (req) => { | ||
if (req.headers['X-Requested-With'] === 'XMLHttpRequest') { | ||
return true; | ||
} | ||
else { | ||
return false; | ||
} | ||
}; | ||
const getHostname = (req) => { | ||
let host = req.get('X-Forwarded-Host'); | ||
if (!host || !compileTrust(req.connection.remoteAddress)) { | ||
host = req.get('Host'); | ||
} | ||
if (!host) | ||
return; | ||
// IPv6 literal support | ||
var offset = host[0] === '[' ? host.indexOf(']') + 1 : 0; | ||
var index = host.indexOf(':', offset); | ||
return index !== -1 ? host.substring(0, index) : host; | ||
}; | ||
const getIP = (req) => { | ||
return proxyAddr(req, compileTrust); | ||
}; | ||
const createETag = (body, encoding) => { | ||
const buf = !Buffer.isBuffer(body) ? Buffer.from(body, encoding) : body; | ||
return etag(buf, { weak: true }); | ||
}; | ||
function setCharset(type, charset) { | ||
const parsed = contentType.parse(type); | ||
parsed.parameters.charset = charset; | ||
return contentType.format(parsed); | ||
} | ||
const json = (_, res) => (body, ...args) => { | ||
res.setHeader('Content-Type', 'application/json'); | ||
if (typeof body === 'object' && body != 'null') { | ||
res.end(JSON.stringify(body, null, 2), ...args); | ||
} | ||
else if (typeof body === 'string') { | ||
res.end(body, ...args); | ||
} | ||
return res; | ||
}; | ||
const send = (req, res) => (body) => { | ||
let bodyToSend = body; | ||
// in case of object - turn it to json | ||
if (typeof body === 'object' && body !== 'null') { | ||
bodyToSend = JSON.stringify(body, null, 2); | ||
} | ||
else { | ||
if (typeof body === 'string') { | ||
// reflect this in content-type | ||
const type = res.getHeader('Content-Type'); | ||
if (typeof type === 'string') { | ||
res.setHeader('Content-Type', setCharset(type, 'utf-8')); | ||
} | ||
} | ||
} | ||
// Set encoding | ||
let encoding = 'utf8'; | ||
// populate ETag | ||
let etag; | ||
if (!res.getHeader('etag') && (etag = createETag(bodyToSend, encoding))) { | ||
res.setHeader('etag', etag); | ||
} | ||
// strip irrelevant headers | ||
if (res.statusCode === 204 || res.statusCode === 304) { | ||
res.removeHeader('Content-Type'); | ||
res.removeHeader('Content-Length'); | ||
res.removeHeader('Transfer-Encoding'); | ||
bodyToSend = ''; | ||
} | ||
if (req.method === 'HEAD') { | ||
res.end(''); | ||
} | ||
if (typeof body === 'object') { | ||
if (body === null) { | ||
res.end(''); | ||
} | ||
else if (Buffer.isBuffer(body)) { | ||
if (!res.getHeader('Content-Type')) { | ||
res.setHeader('content-type', 'application/octet-stream'); | ||
} | ||
} | ||
else { | ||
json(req, res)(bodyToSend, encoding) ; | ||
} | ||
} | ||
else { | ||
{ | ||
// respond with encoding | ||
res.end(bodyToSend, encoding); | ||
} | ||
} | ||
return res; | ||
}; | ||
const status = (_, res) => (status) => { | ||
res.statusCode = status; | ||
return res; | ||
}; | ||
const notFound = () => (_, res) => { | ||
if (!res.writableEnded) { | ||
res.statusCode = 404; | ||
res.end('Not found'); | ||
} | ||
}; | ||
const METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'HEAD']; | ||
const createHandler = ({ url, handler, method }) => ({ | ||
method, | ||
handler: handler || url, | ||
url: typeof url === 'string' ? url : '*' | ||
}); | ||
class App { | ||
constructor() { | ||
this.routes = []; | ||
this.middleware = []; | ||
} | ||
get(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'GET' })); | ||
return this; | ||
} | ||
post(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'POST' })); | ||
return this; | ||
} | ||
put(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'PUT' })); | ||
return this; | ||
} | ||
patch(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'PATCH' })); | ||
return this; | ||
} | ||
head(url, handler) { | ||
this.routes.push(createHandler({ url, handler, method: 'HEAD' })); | ||
return this; | ||
} | ||
all(url, handler) { | ||
for (const method of METHODS) { | ||
this.routes.push(createHandler({ url, handler, method })); | ||
} | ||
return this; | ||
} | ||
use(handler) { | ||
this.middleware.push({ | ||
handler | ||
}); | ||
return this; | ||
} | ||
listen(port, cb = () => console.log(`Started on http://${host}:${port}`), host = 'localhost', backlog) { | ||
// @ts-ignore | ||
const server = http.createServer((req, res) => { | ||
/// Define extensions | ||
/* | ||
Request extensions | ||
*/ | ||
const proto = getProtocol(req); | ||
const secure = proto === 'https'; | ||
req.protocol = proto; | ||
req.secure = secure; | ||
req.connection = Object.assign(req.socket, { | ||
encrypted: secure | ||
}); | ||
req.query = getQueryParams(req.url); | ||
req.get = getHeader(req); | ||
req.range = getRangeFromHeader(req); | ||
req.xhr = checkIfXMLHttpRequest(req); | ||
req.hostname = getHostname(req); | ||
/* | ||
Response extensions | ||
*/ | ||
res.send = send(req, res); | ||
res.json = json(req, res); | ||
res.status = status(req, res); | ||
this.routes.map(({ url, method, handler }) => { | ||
if (req.method === method) { | ||
if (url && req.url && rg(url).pattern.test(req.url)) { | ||
req.params = getURLParams(req.url, url); | ||
req.route = getRouteFromApp(this, handler); | ||
if (!res.writableEnded) { | ||
res.statusCode = 200; | ||
handler(req, res); | ||
} | ||
} | ||
} | ||
}); | ||
let middleware = this.middleware.filter(m => m.handler.name !== 'logger'); | ||
middleware.push({ handler: notFound() }); | ||
const logger = this.middleware.find(m => m.handler.name === 'logger'); | ||
if (logger) | ||
middleware.push(logger); | ||
middleware.map(({ handler }) => { | ||
handler(req, res); | ||
}); | ||
}); | ||
return server.listen(port, host, backlog, cb); | ||
} | ||
} | ||
exports.App = App; | ||
exports.METHODS = METHODS; | ||
exports.checkIfXMLHttpRequest = checkIfXMLHttpRequest; | ||
exports.compileTrust = compileTrust; | ||
exports.getHeader = getHeader; | ||
exports.getHostname = getHostname; | ||
exports.getIP = getIP; | ||
exports.getProtocol = getProtocol; | ||
exports.getQueryParams = getQueryParams; | ||
exports.getRangeFromHeader = getRangeFromHeader; | ||
exports.getRouteFromApp = getRouteFromApp; | ||
exports.getURLParams = getURLParams; | ||
exports.json = json; | ||
exports.notFound = notFound; | ||
exports.send = send; | ||
exports.status = status; | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("http"),r=e(require("regexparam")),s=require("url"),n=e(require("proxy-addr")),o=e(require("range-parser")),u=require("content-type"),a=e(require("@tinyhttp/etag"));const d=(e="/")=>s.parse(e,!0).query,i=(e="/",t="/")=>((e,t)=>{let r=0,s={},n=t.pattern.exec(e);for(;r<t.keys.length;)s[t.keys[r]]=(null==n?void 0:n[++r])||null;return s})(e,r(t)),p=(e,t)=>e.routes.find(e=>e.handler.name===t.name),l=e=>"function"==typeof e?e:!0===e?function(){return!0}:"number"==typeof e?(t,r)=>{if(e)return r<e}:("string"==typeof e&&(e=e.split(/ *, */)),n.compile(e||[])),h=e=>{const t=e.connection.encrypted?"https":"http";if(!l(e.connection.remoteAddress))return t;const r=e.headers["X-Forwarded-Proto"]||t,s=r.indexOf(",");return-1!==s?r.substring(0,s).trim():r.trim()},c=e=>t=>e.headers[t.toLowerCase()],f=e=>(t,r)=>{const s=e.get("Range");if(s)return o(t,s,r)},m=e=>"XMLHttpRequest"===e.headers["X-Requested-With"],g=e=>{let t=e.get("X-Forwarded-Host");if(t&&l(e.connection.remoteAddress)||(t=e.get("Host")),t){var r="["===t[0]?t.indexOf("]")+1:0,s=t.indexOf(":",r);return-1!==s?t.substring(0,s):t}},y=(e,t)=>{const r=Buffer.isBuffer(e)?e:Buffer.from(e,t);return a(r,{weak:!0})};const x=(e,t)=>(e,...r)=>(t.setHeader("Content-Type","application/json"),"object"==typeof e&&"null"!=e?t.end(JSON.stringify(e,null,2),...r):"string"==typeof e&&t.end(e,...r),t),H=(e,t)=>r=>{let s=r;if("object"==typeof r&&"null"!==r)s=JSON.stringify(r,null,2);else if("string"==typeof r){const e=t.getHeader("Content-Type");"string"==typeof e&&t.setHeader("Content-Type",function(e,t){const r=u.parse(e);return r.parameters.charset=t,u.format(r)}(e,"utf-8"))}let n;return!t.getHeader("etag")&&(n=y(s,"utf8"))&&t.setHeader("etag",n),204!==t.statusCode&&304!==t.statusCode||(t.removeHeader("Content-Type"),t.removeHeader("Content-Length"),t.removeHeader("Transfer-Encoding"),s=""),"HEAD"===e.method&&t.end(""),"object"==typeof r?null===r?t.end(""):Buffer.isBuffer(r)?t.getHeader("Content-Type")||t.setHeader("content-type","application/octet-stream"):x(0,t)(s,"utf8"):t.end(s,"utf8"),t},T=(e,t)=>e=>(t.statusCode=e,t),C=()=>(e,t)=>{t.writableEnded||(t.statusCode=404,t.end("Not found"))},b=["GET","POST","PUT","PATCH","HEAD"],q=({url:e,handler:t,method:r})=>({method:r,handler:t||e,url:"string"==typeof e?e:"*"});exports.App=class{constructor(){this.routes=[],this.middleware=[]}get(e,t){return this.routes.push(q({url:e,handler:t,method:"GET"})),this}post(e,t){return this.routes.push(q({url:e,handler:t,method:"POST"})),this}put(e,t){return this.routes.push(q({url:e,handler:t,method:"PUT"})),this}patch(e,t){return this.routes.push(q({url:e,handler:t,method:"PATCH"})),this}head(e,t){return this.routes.push(q({url:e,handler:t,method:"HEAD"})),this}all(e,t){for(const r of b)this.routes.push(q({url:e,handler:t,method:r}));return this}use(e){return this.middleware.push({handler:e}),this}listen(e,s=(()=>console.log(`Started on http://${n}:${e}`)),n="localhost",o){return t.createServer((e,t)=>{const s=h(e),n="https"===s;e.protocol=s,e.secure=n,e.connection=Object.assign(e.socket,{encrypted:n}),e.query=d(e.url),e.get=c(e),e.range=f(e),e.xhr=m(e),e.hostname=g(e),t.send=H(e,t),t.json=x(0,t),t.status=T(0,t),this.routes.map(({url:s,method:n,handler:o})=>{e.method===n&&s&&e.url&&r(s).pattern.test(e.url)&&(e.params=i(e.url,s),e.route=p(this,o),t.writableEnded||(t.statusCode=200,o(e,t)))});let o=this.middleware.filter(e=>"logger"!==e.handler.name);o.push({handler:(e,t)=>{t.writableEnded||(t.statusCode=404,t.end("Not found"))}});const u=this.middleware.find(e=>"logger"===e.handler.name);u&&o.push(u),o.map(({handler:r})=>{r(e,t)})}).listen(e,n,o,s)}},exports.METHODS=b,exports.checkIfXMLHttpRequest=m,exports.compileTrust=l,exports.getHeader=c,exports.getHostname=g,exports.getIP=e=>n(e,l),exports.getProtocol=h,exports.getQueryParams=d,exports.getRangeFromHeader=f,exports.getRouteFromApp=p,exports.getURLParams=i,exports.json=x,exports.notFound=C,exports.send=H,exports.status=T; |
{ | ||
"name": "@tinyhttp/app", | ||
"version": "0.1.17", | ||
"version": "0.1.20", | ||
"description": "tinyhttp core", | ||
@@ -20,5 +20,2 @@ "homepage": "https://github.com/talentlessguy/tinyhttp", | ||
}, | ||
"scripts": { | ||
"build": "rollup -c" | ||
}, | ||
"keywords": [ | ||
@@ -34,3 +31,3 @@ "tinyhttp", | ||
"dependencies": { | ||
"@tinyhttp/etag": "^0.1.15", | ||
"@tinyhttp/etag": "workspace:*", | ||
"content-type": "^1.0.4", | ||
@@ -45,4 +42,3 @@ "proxy-addr": "^2.0.6", | ||
"@types/range-parser": "^1.2.3" | ||
}, | ||
"gitHead": "584a7d9a98e23543ef5285af59532a583c578d11" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
13050
97
2
3
- Removed@tinyhttp/etag@0.1.26(transitive)
Updated@tinyhttp/etag@workspace:*