diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index a61f846..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "printWidth": 100, - "singleQuote": true, - "bracketSpacing": true, - "semi": false, - "arrowParens": "always" -} diff --git a/.taprc b/.taprc deleted file mode 100644 index 2ba0c14..0000000 --- a/.taprc +++ /dev/null @@ -1,2 +0,0 @@ -files: - - test-tap/**/*.test.js diff --git a/README.md b/README.md index 0b081f1..0d84cf9 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![CI](https://github.com/fastify/fastify-request-context/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/fastify-request-context/actions/workflows/ci.yml) +[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard) Request-scoped storage support, based on [AsyncLocalStorage](https://nodejs.org/api/async_context.html#asynchronous-context-tracking). @@ -13,14 +14,14 @@ nor will variables remain available once a request is completed. Frequent use-cases are persisting request-aware logger instances and user authorization information. - - ## Install + ``` npm i @fastify/request-context ``` ### Compatibility + | Plugin version | Fastify version | | ---------------|-----------------| | `>=6.x` | `^5.x` | @@ -29,7 +30,6 @@ npm i @fastify/request-context | `^1.x` | `^2.x` | | `^1.x` | `^1.x` | - Please note that if a Fastify version is out of support, then so are the corresponding versions of this plugin in the table above. See [Fastify's LTS policy](https://github.com/fastify/fastify/blob/main/docs/Reference/LTS.md) for more details. @@ -133,7 +133,7 @@ return app.ready() In TypeScript you are expected to augment the module to type your context: ```ts -import {requestContext} from '@fastify/request-context' +import { requestContext } from '@fastify/request-context' declare module '@fastify/request-context' { interface RequestContextData { diff --git a/eslint.config.js b/eslint.config.js index f57a494..db14c00 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,18 +1,6 @@ 'use strict' -const globals = require('globals') -const js = require('@eslint/js') -const prettier = require('eslint-plugin-prettier/recommended') - -module.exports = [ - { - languageOptions: { - globals: { - ...globals.node, - ...globals.jest, - }, - }, - }, - js.configs.recommended, - prettier, -] +module.exports = require('neostandard')({ + ignores: require('neostandard').resolveIgnoresFromGitignore(), + ts: true, +}) diff --git a/index.js b/index.js index cb86172..a7f31ec 100644 --- a/index.js +++ b/index.js @@ -24,14 +24,14 @@ const requestContext = { }, } -function fastifyRequestContext(fastify, opts, next) { +function fastifyRequestContext (fastify, opts, next) { fastify.decorate('requestContext', requestContext) fastify.decorateRequest('requestContext', { getter: () => requestContext }) fastify.decorateRequest(asyncResourceSymbol, null) const hook = opts.hook || 'onRequest' const hasDefaultStoreValuesFactory = typeof opts.defaultStoreValues === 'function' - fastify.addHook(hook, function requestContextHook(req, _res, done) { + fastify.addHook(hook, function requestContextHook (req, _res, done) { const defaultStoreValues = hasDefaultStoreValuesFactory ? opts.defaultStoreValues(req) : opts.defaultStoreValues @@ -51,7 +51,7 @@ function fastifyRequestContext(fastify, opts, next) { // in a different async context, as req/res may emit events in a different context. // Related to https://github.com/nodejs/node/issues/34430 and https://github.com/nodejs/node/issues/33723 if (hook === 'onRequest' || hook === 'preParsing') { - fastify.addHook('preValidation', function requestContextPreValidationHook(req, _res, done) { + fastify.addHook('preValidation', function requestContextPreValidationHook (req, _res, done) { const asyncResource = req[asyncResourceSymbol] asyncResource.runInAsyncScope(done, req.raw) }) diff --git a/package.json b/package.json index a3fffab..c8df0ca 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "test": "npm run test:unit && npm run test:typescript", "test:unit": "c8 --100 node --test", "test:typescript": "tsd", - "lint": "eslint \"test/**/*.js\" \"test-tap/**/*.js\" index.js", - "prettier": "prettier --write \"{lib,test,test-tap}/**/*.js\" index.js \"types/**/*.ts\"" + "lint": "eslint", + "lint:fix": "eslint --fix" }, "dependencies": { "fastify-plugin": "^5.0.0" @@ -25,11 +25,9 @@ "devDependencies": { "@types/node": "^25.0.3", "c8": "^11.0.0", - "eslint": "^10.0.2", - "eslint-config-prettier": "^10.0.1", - "eslint-plugin-prettier": "^5.1.3", + "eslint": "^9.39.0", "fastify": "^5.0.0", - "prettier": "^3.2.5", + "neostandard": "^0.12.0", "superagent": "^10.0.0", "tsd": "^0.33.0" }, diff --git a/test/internal/appInitializer.js b/test/internal/appInitializer.js index b7db375..5efd8f0 100644 --- a/test/internal/appInitializer.js +++ b/test/internal/appInitializer.js @@ -3,7 +3,7 @@ const fastify = require('fastify') const { fastifyRequestContext } = require('../..') -function initAppGet(endpoint) { +function initAppGet (endpoint) { const app = fastify({ logger: true }) app.register(fastifyRequestContext) @@ -11,7 +11,7 @@ function initAppGet(endpoint) { return app } -function initAppPost(endpoint) { +function initAppPost (endpoint) { const app = fastify({ logger: true }) app.register(fastifyRequestContext) @@ -20,7 +20,7 @@ function initAppPost(endpoint) { return app } -function initAppPostWithPrevalidation(endpoint) { +function initAppPostWithPrevalidation (endpoint) { const app = fastify({ logger: true }) app.register(fastifyRequestContext, { hook: 'preValidation' }) @@ -40,7 +40,7 @@ function initAppPostWithPrevalidation(endpoint) { return app } -function initAppPostWithAllPlugins(endpoint, requestHook) { +function initAppPostWithAllPlugins (endpoint, requestHook) { const app = fastify({ logger: true }) app.register(fastifyRequestContext, { hook: requestHook }) @@ -85,7 +85,7 @@ function initAppPostWithAllPlugins(endpoint, requestHook) { return app } -function initAppGetWithDefaultStoreValues(endpoint, defaultStoreValues) { +function initAppGetWithDefaultStoreValues (endpoint, defaultStoreValues) { const app = fastify({ logger: true }) app.register(fastifyRequestContext, { defaultStoreValues, diff --git a/test/internal/testService.js b/test/internal/testService.js index f098a8f..6f616fd 100644 --- a/test/internal/testService.js +++ b/test/internal/testService.js @@ -4,29 +4,29 @@ const { requestContext } = require('../..') // Test class to check if nested calls with promises work correctly with async local storage class TestService { - constructor(fastify) { + constructor (fastify) { this.appRequestContext = fastify.requestContext } - processRequest(requestId) { + processRequest (requestId) { return this.fetchData().then(() => { const testValueFromApp = this.appRequestContext.get('testKey') const testValueFromLib = requestContext.get('testKey') if (testValueFromApp !== `testValue${requestId}`) { throw new Error( - `Wrong value retrieved from app context for request ${requestId}: ${testValueFromApp}`, + `Wrong value retrieved from app context for request ${requestId}: ${testValueFromApp}` ) } if (testValueFromLib !== `testValue${requestId}`) { throw new Error( - `Wrong value retrieved from lib context for request ${requestId}: ${testValueFromLib}`, + `Wrong value retrieved from lib context for request ${requestId}: ${testValueFromLib}` ) } }) } - fetchData() { + fetchData () { return new Promise((resolve) => { setTimeout(resolve, 10) }) diff --git a/test/internal/watcherService.js b/test/internal/watcherService.js index 107f2c5..18eb062 100644 --- a/test/internal/watcherService.js +++ b/test/internal/watcherService.js @@ -4,7 +4,7 @@ const { executionAsyncId, createHook, AsyncResource } = require('node:async_hook const { EventEmitter } = require('node:events') class CustomResource extends AsyncResource { - constructor(type, traceId) { + constructor (type, traceId) { super(type) this.traceId = traceId @@ -12,7 +12,7 @@ class CustomResource extends AsyncResource { } class AsyncWatcher extends EventEmitter { - setupInitHook() { + setupInitHook () { // init is called during object construction. The resource may not have // completed construction when this callback runs, therefore all fields of the // resource referenced by "asyncId" may not have been populated. @@ -28,7 +28,7 @@ class AsyncWatcher extends EventEmitter { return this } - setupDestroyHook() { + setupDestroyHook () { // Destroy is called when an AsyncWrap instance is destroyed. this.destroy = (asyncId) => { this.emit('DESTROY', { @@ -39,7 +39,7 @@ class AsyncWatcher extends EventEmitter { return this } - start() { + start () { createHook({ init: this.init.bind(this), destroy: this.destroy.bind(this), @@ -50,7 +50,7 @@ class AsyncWatcher extends EventEmitter { } class AsyncHookContainer { - constructor(types) { + constructor (types) { const checkedTypes = types const idMap = new Map() @@ -86,7 +86,7 @@ class AsyncHookContainer { this.watcher = watcher } - getStore(asyncId) { + getStore (asyncId) { let resource = this.resourceMap.get(asyncId) if (resource != null) { diff --git a/test/requestContextPlugin.e2e.spec.js b/test/requestContextPlugin.e2e.spec.js index 6f2246f..82b9558 100644 --- a/test/requestContextPlugin.e2e.spec.js +++ b/test/requestContextPlugin.e2e.spec.js @@ -1,3 +1,4 @@ +/* eslint-disable promise/param-names */ 'use strict' const request = require('superagent') @@ -26,7 +27,7 @@ describe('requestContextPlugin E2E', () => { const route = (req) => { const requestId = req.requestContext.get('testKey') - function prepareReply() { + function prepareReply () { return testService.processRequest(requestId.replace('testValue', '')).then(() => { const storedValue = req.requestContext.get('testKey') return Promise.resolve({ storedValue }) @@ -104,7 +105,7 @@ describe('requestContextPlugin E2E', () => { const requestId = `testValue${preHandlerValue}` - function prepareReply() { + function prepareReply () { return testService.processRequest(requestId.replace('testValue', '')).then(() => { const storedValue = req.requestContext.get('preValidation') return Promise.resolve({ storedValue: `testValue${storedValue}` }) diff --git a/test-tap/requestContextPlugin.e2e.test.js b/test/requestContextPlugin.e2e.test.js similarity index 99% rename from test-tap/requestContextPlugin.e2e.test.js rename to test/requestContextPlugin.e2e.test.js index 36e0fa5..05f23da 100644 --- a/test-tap/requestContextPlugin.e2e.test.js +++ b/test/requestContextPlugin.e2e.test.js @@ -1,3 +1,4 @@ +/* eslint-disable promise/param-names */ 'use strict' const fastify = require('fastify') @@ -29,7 +30,7 @@ test('correctly preserves values set in prevalidation phase within single POST r const route = (req) => { const requestId = req.requestContext.get('testKey') - function prepareReply() { + function prepareReply () { return testService.processRequest(requestId.replace('testValue', '')).then(() => { const storedValue = req.requestContext.get('testKey') return Promise.resolve({ storedValue }) @@ -107,7 +108,7 @@ test('correctly preserves values set in multiple phases within single POST reque const requestId = `testValue${preHandlerValue}` - function prepareReply() { + function prepareReply () { return testService.processRequest(requestId.replace('testValue', '')).then(() => { const storedValue = req.requestContext.get('preValidation') return Promise.resolve({ storedValue: `testValue${storedValue}` }) diff --git a/test/requestContextPlugin.spec.js b/test/requestContextPlugin.spec.js index e6eaf22..d4c701c 100644 --- a/test/requestContextPlugin.spec.js +++ b/test/requestContextPlugin.spec.js @@ -1,3 +1,4 @@ +/* eslint-disable promise/param-names */ 'use strict' const { @@ -24,7 +25,7 @@ describe('requestContextPlugin', () => { const promiseRequest2 = new Promise((resolveRequest2Promise) => { const promiseRequest1 = new Promise((resolveRequest1Promise) => { const route = (req, reply) => { - function prepareReply() { + function prepareReply () { return testService.processRequest(requestId).then(() => { const storedValue = req.requestContext.get('testKey') reply.status(200).send({ @@ -99,7 +100,7 @@ describe('requestContextPlugin', () => { const promiseRequest2 = new Promise((resolveRequest2Promise) => { const promiseRequest1 = new Promise((resolveRequest1Promise) => { const route = (req, reply) => { - function prepareReply() { + function prepareReply () { return testService.processRequest(requestId).then(() => { const storedValue = req.requestContext.get('testKey') reply.status(200).send({ @@ -176,7 +177,7 @@ describe('requestContextPlugin', () => { const route = (req, reply) => { const requestId = req.requestContext.get('testKey') - function prepareReply() { + function prepareReply () { return testService.processRequest(requestId.replace('testValue', '')).then(() => { const storedValue = req.requestContext.get('testKey') reply.status(200).send({ @@ -289,7 +290,7 @@ describe('requestContextPlugin', () => { const promiseRequest2 = new Promise((resolveRequest2Promise) => { const promiseRequest1 = new Promise((resolveRequest1Promise) => { const route = (req, reply) => { - function prepareReply() { + function prepareReply () { return testService.processRequest(requestId).then(() => { const storedValue = req.requestContext.get('testKey') reply.status(204).header('storedvalue', storedValue).send() diff --git a/tsconfig.json b/tsconfig.json index c9ce99d..831e273 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,11 +2,11 @@ "compilerOptions": { "outDir": "dist", "module": "commonjs", - "target": "es2015", + "target": "es2022", "sourceMap": true, "declaration": true, "declarationMap": false, - "types": ["node", "jest"], + "types": ["node"], "strict": true, "moduleResolution": "node", "noUnusedLocals": false, @@ -17,15 +17,10 @@ "noImplicitThis": true, "strictNullChecks": true, "importHelpers": true, - "baseUrl": ".", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "exactOptionalPropertyTypes": true }, - "exclude": [ - "node_modules", - "test", - "dist" - ] + "exclude": ["node_modules", "test", "dist"] } diff --git a/types/index.d.ts b/types/index.d.ts index 303cedc..e09a7a9 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -69,7 +69,7 @@ declare namespace fastifyRequestContext { export { fastifyRequestContext as default } } -declare function fastifyRequestContext( +declare function fastifyRequestContext ( ...params: Parameters ): ReturnType export = fastifyRequestContext diff --git a/types/index.test-d.ts b/types/index.test-d.ts index 0f62272..2240d8a 100644 --- a/types/index.test-d.ts +++ b/types/index.test-d.ts @@ -68,6 +68,7 @@ expectType>(asyncLocalStorage) const getHandler: RouteHandlerMethod = function (request, _reply) { expectType(request.requestContext) } +expectType(getHandler) expectType(requestContext.get('a')) expectType(requestContext.get('log'))