diff --git a/benchmark/bench.js b/benchmark/bench.js index 364a603..ae63011 100644 --- a/benchmark/bench.js +++ b/benchmark/bench.js @@ -17,7 +17,9 @@ function createServer (sessionPlugin, cookiePlugin, storeType) { if (storeType === 'redis') { if (!redisClient) { - redisClient = new Redis() + redisClient = new Redis({ + clientInfoTag: fastifySession.getDefaultClientInfoTag() + }) } store = new RedisStore({ client: redisClient }) } else if (storeType === 'file') { diff --git a/examples/redis.js b/examples/redis.js index e3355e2..4fcd1bf 100644 --- a/examples/redis.js +++ b/examples/redis.js @@ -10,7 +10,8 @@ const fastify = Fastify() const store = new RedisStore({ client: new Redis({ - enableAutoPipelining: true + enableAutoPipelining: true, + clientInfoTag: fastifySession.getDefaultClientInfoTag() }) }) diff --git a/lib/fastifySession.js b/lib/fastifySession.js index 56aa6f4..fef63f3 100644 --- a/lib/fastifySession.js +++ b/lib/fastifySession.js @@ -5,6 +5,20 @@ const idGenerator = require('./idGenerator')() const Store = require('./store') const Session = require('./session') +/** + * Get the default clientInfoTag for identifying the framework in Redis CLIENT SETINFO. + * This can be used when creating Redis clients for session stores. + * @returns {string} The client info tag (e.g., "fastify-session_v11.1.1") + */ +function getDefaultClientInfoTag () { + try { + const version = require('../package.json').version + return `fastify-session_v${version}` + } catch { + return 'fastify-session' + } +} + function fastifySession (fastify, options, next) { const error = checkOptions(options) if (error) { @@ -276,3 +290,4 @@ module.exports.fastifySession = fastifySession module.exports.Store = Store module.exports.MemoryStore = Store +module.exports.getDefaultClientInfoTag = getDefaultClientInfoTag diff --git a/test/clientInfoTag.test.js b/test/clientInfoTag.test.js new file mode 100644 index 0000000..eb6df3f --- /dev/null +++ b/test/clientInfoTag.test.js @@ -0,0 +1,44 @@ +'use strict' + +const test = require('node:test') +const fastifySession = require('..') + +test('getDefaultClientInfoTag should return version tag', (t) => { + t.plan(1) + const tag = fastifySession.getDefaultClientInfoTag() + t.assert.match(tag, /^fastify-session_v\d+\.\d+\.\d+$/) +}) + +test('getDefaultClientInfoTag should be accessible from module', (t) => { + t.plan(1) + t.assert.strictEqual(typeof fastifySession.getDefaultClientInfoTag, 'function') +}) + +test('getDefaultClientInfoTag should fallback to fastify-session when package.json version is unavailable', (t) => { + t.plan(1) + + // Mock require to simulate missing package.json + const Module = require('module') + const originalRequire = Module.prototype.require + + Module.prototype.require = function (id) { + if (id === '../package.json') { + throw new Error('Cannot find module') + } + return originalRequire.apply(this, arguments) + } + + // Clear the require cache + delete require.cache[require.resolve('..')] + + const fastifySessionMocked = require('..') + const tag = fastifySessionMocked.getDefaultClientInfoTag() + + // Restore original require + Module.prototype.require = originalRequire + + // Clear cache again + delete require.cache[require.resolve('..')] + + t.assert.strictEqual(tag, 'fastify-session') +}) diff --git a/types/types.d.ts b/types/types.d.ts index 89d1a7d..60d2683 100644 --- a/types/types.d.ts +++ b/types/types.d.ts @@ -24,6 +24,7 @@ declare module 'fastify' { type FastifySession = FastifyPluginCallback & { Store: fastifySession.MemoryStore, MemoryStore: fastifySession.MemoryStore, + getDefaultClientInfoTag: () => string, } type Callback = (err?: any) => void @@ -201,6 +202,14 @@ declare namespace fastifySession { export const Store: MemoryStore + /** + * Get the default clientInfoTag for identifying the framework in Redis CLIENT SETINFO. + * This can be used when creating Redis clients for session stores. + * @link https://redis.io/docs/latest/commands/client-setinfo/ + * @returns The client info tag (e.g., "fastify-session_v11.1.1") + */ + export function getDefaultClientInfoTag (): string + export const fastifySession: FastifySession export { fastifySession as default } } diff --git a/types/types.test-d.ts b/types/types.test-d.ts index 3360525..2142cd8 100644 --- a/types/types.test-d.ts +++ b/types/types.test-d.ts @@ -31,6 +31,7 @@ declare module 'fastify' { expectType(plugin.Store) expectType(plugin.MemoryStore) +expectType(plugin.getDefaultClientInfoTag()) const secret = 'ABCDEFGHIJKLNMOPQRSTUVWXYZ012345' @@ -63,6 +64,14 @@ app.register(plugin, { secret, store: new RedisStore({ client: new Redis() }) }) +app.register(plugin, { + secret, + store: new RedisStore({ + client: new Redis({ + clientInfoTag: plugin.getDefaultClientInfoTag() + }) + }) +}) app.register(plugin, { secret, store: MongoStore.create({ mongoUrl: 'mongodb://connection-string' })