@bsnext/fastify-bowser
Advanced tools
Comparing version 1.0.0 to 1.2.0
declare module "fastify" { | ||
interface FastifyRequest { | ||
useragent: { | ||
ua: string; | ||
browser: { | ||
name: string | undefined; | ||
version: string | undefined; | ||
name?: string; | ||
version?: string; | ||
}; | ||
os: { | ||
name: string | undefined; | ||
version: string | undefined; | ||
versionName: string | undefined; | ||
name?: string; | ||
version?: string; | ||
versionName?: string; | ||
}; | ||
platform: { | ||
type: string | undefined; | ||
type?: string; | ||
vendor?: string; | ||
model?: string; | ||
}; | ||
engine: { | ||
name: string | undefined; | ||
name?: string; | ||
version?: string; | ||
}; | ||
@@ -20,0 +22,0 @@ }; |
@@ -6,3 +6,3 @@ "use strict"; | ||
const undefinedUserAgentInfo = { | ||
browser: { name: `''`, version: `''` }, | ||
browser: { name: ``, version: `` }, | ||
os: {}, | ||
@@ -27,34 +27,35 @@ platform: {}, | ||
const isCaching = initOptions.cache; | ||
let cacheLimit = initOptions.cacheLimit || 100; | ||
let cacheSize = 0; | ||
let cachePool = Object.create(null); | ||
function purgeCache() { | ||
cachePool = Object.create(null); | ||
cacheSize = 0; | ||
} | ||
if (isCaching) { | ||
setInterval(purgeCache, (initOptions.cachePurgeTime || (60 * 5)) * 1000); | ||
const cachePool = new LRUCache(initOptions.cacheLimit || 100); | ||
if (initOptions.cachePurgeTime) { | ||
setInterval(cachePool.clear.bind(cachePool), initOptions.cachePurgeTime * 1000); | ||
} | ||
fastify.decorateRequest(`useragent`, { | ||
getter() { | ||
const userAgent = this.headers[`user-agent`]; | ||
if ((userAgent === undefined) || (userAgent === ``)) { | ||
return undefinedUserAgentInfo; | ||
} | ||
const cachedQuery = cachePool.get(userAgent); | ||
if (cachedQuery !== undefined) { | ||
return cachedQuery; | ||
} | ||
const uaParseResult = Bowser.parse(userAgent); | ||
cachePool.set(userAgent, uaParseResult); | ||
return uaParseResult; | ||
} | ||
}); | ||
} | ||
fastify.decorateRequest(`useragent`, { | ||
getter() { | ||
const userAgent = this.headers[`user-agent`]; | ||
if ((userAgent === undefined) || (userAgent === ``)) { | ||
return undefinedUserAgentInfo; | ||
} | ||
const cachedQuery = cachePool[userAgent]; | ||
if (isCaching && cachedQuery) { | ||
return cachedQuery; | ||
} | ||
const uaParseResult = Bowser.parse(userAgent); | ||
if (isCaching) { | ||
if (cacheSize >= cacheLimit) { | ||
purgeCache(); | ||
else { | ||
fastify.decorateRequest(`useragent`, { | ||
getter() { | ||
const userAgent = this.headers[`user-agent`]; | ||
if ((userAgent === undefined) || (userAgent === ``)) { | ||
return undefinedUserAgentInfo; | ||
} | ||
cacheSize = cacheSize + 1; | ||
cachePool[userAgent] = uaParseResult; | ||
const uaParseResult = Bowser.parse(userAgent); | ||
return uaParseResult; | ||
} | ||
; | ||
return uaParseResult; | ||
} | ||
}); | ||
}); | ||
} | ||
done(); | ||
@@ -65,2 +66,85 @@ }, { | ||
}); | ||
class LRUCache { | ||
constructor(limit = 100) { | ||
this.size = 0; | ||
this.head = null; | ||
this.tail = null; | ||
this.limit = limit; | ||
this.cache = {}; | ||
} | ||
moveToHead(node) { | ||
if (this.head === node) { | ||
return; | ||
} | ||
if (node.prev !== null) { | ||
node.prev.next = node.next; | ||
} | ||
if (node.next !== null) { | ||
node.next.prev = node.prev; | ||
} | ||
if (this.tail === node) { | ||
this.tail = node.prev; | ||
} | ||
node.next = this.head; | ||
node.prev = null; | ||
if (this.head !== null) { | ||
this.head.prev = node; | ||
} | ||
this.head = node; | ||
if (this.tail === null) { | ||
this.tail = node; | ||
} | ||
} | ||
removeTail() { | ||
if (this.tail === null) { | ||
return; | ||
} | ||
const tailNode = this.tail; | ||
delete this.cache[tailNode.key]; | ||
if (tailNode.prev !== null) { | ||
this.tail = tailNode.prev; | ||
this.tail.next = null; | ||
} | ||
else { | ||
this.head = null; | ||
this.tail = null; | ||
} | ||
this.size--; | ||
} | ||
get(key) { | ||
const node = this.cache[key]; | ||
if (node === undefined) { | ||
return undefined; | ||
} | ||
this.moveToHead(node); | ||
return node.value; | ||
} | ||
set(key, value) { | ||
let node = this.cache[key]; | ||
if (node !== undefined) { | ||
node.value = value; | ||
this.moveToHead(node); | ||
} | ||
else { | ||
node = { | ||
key: key, | ||
value: value, | ||
prev: null, | ||
next: null, | ||
}; | ||
this.cache[key] = node; | ||
this.moveToHead(node); | ||
this.size++; | ||
if (this.size > this.limit) { | ||
this.removeTail(); | ||
} | ||
} | ||
} | ||
clear() { | ||
this.cache = {}; | ||
this.head = null; | ||
this.tail = null; | ||
this.size = 0; | ||
} | ||
} | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@bsnext/fastify-bowser", | ||
"version": "1.0.0", | ||
"version": "1.2.0", | ||
"description": "A plugin for Fastify that adds the 'request.useragent' property to get header 'user-agent' parsed data.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
# Fastify-Bowser | ||
![Build & Test](https://github.com/bsnext/fastify-bowser/actions/workflows/build_n_test.yml/badge.svg) | ||
![Node.JS Supported](https://badgen.net/static/Node.JS/%3E=19.0.0/green) | ||
![Fastify Supported](https://badgen.net/static/Fastify/%3E=14/green) | ||
![Fastify Supported](https://badgen.net/static/Fastify/%3E=4.14.0/green) | ||
![Install Size](https://badgen.net/packagephobia/install/@bsnext/fastify-bowser) | ||
@@ -36,6 +36,7 @@ ![Dependencies](https://badgen.net/bundlephobia/dependency-count/@bsnext/fastify-bowser) | ||
// Cache limit. Will be automatically purged, if cache size reach limit. | ||
cacheLimit: number = 100; | ||
cacheLimit?: number = 100; | ||
// Automatically cache purge interval in milliseconds. | ||
cachePurgeTime: number = 60 * 5; | ||
// Automatically cache purge interval in seconds. | ||
// Disabled by default | ||
cachePurgeTime?: number; | ||
}); | ||
@@ -42,0 +43,0 @@ |
Sorry, the diff of this file is not supported yet
15272
178
67