Security News
The Risks of Misguided Research in Supply Chain Security
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
@nestjs-steroids/async-context
Advanced tools
Zero-dependency module for NestJS that allow to track context between async call
npm install @nestjs-steroids/async-context
yarn add @nestjs-steroids/async-context
pnpm install @nestjs-steroids/async-context
The first step is to register AsyncContext
inside interceptor (or middleware)
src/async-context.interceptor.ts
import { randomUUID } from 'crypto'
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler
} from '@nestjs/common'
import { AsyncContext } from '@nestjs-steroids/async-context'
import { Observable } from 'rxjs'
@Injectable()
export class AsyncContextInterceptor implements NestInterceptor {
constructor (private readonly ac: AsyncContext<string, any>) {}
intercept (context: ExecutionContext, next: CallHandler): Observable<any> {
this.ac.register() // Important to call .register or .registerCallback (good for middleware)
this.ac.set('traceId', randomUUID()) // Setting default value traceId
return next.handle()
}
}
The second step is to register AsyncContextModule
and interceptor inside main module
src/app.module.ts
import { APP_INTERCEPTOR } from '@nestjs/core';
import { Module } from '@nestjs/common';
import { AsyncContextModule } from '@nestjs-steroids/async-context';
import { AsyncContextInterceptor } from './async-context.interceptor';
@Module({
imports: [
AsyncContextModule.forRoot()
],
providers: [
{
provide: APP_INTERCEPTOR,
useClass: AsyncContextInterceptor,
},
],
})
export class AppModule {}
The last step is to inject AsyncContext
inside controller or service and use it
src/app.controller.ts
import { Controller, Get, Logger } from '@nestjs/common'
import { AppService } from './app.service'
import { AsyncContext } from '@nestjs-steroids/async-context'
@Controller()
export class AppController {
constructor (
private readonly appService: AppService,
private readonly asyncContext: AsyncContext<string, string>,
private readonly logger: Logger
) {}
@Get()
getHello (): string {
this.logger.log('AppController.getHello', this.asyncContext.get('traceId'))
process.nextTick(() => {
this.logger.log(
'AppController.getHello -> nextTick',
this.asyncContext.get('traceId')
)
setTimeout(() => {
this.logger.log(
'AppController.getHello -> nextTick -> setTimeout',
this.asyncContext.get('traceId')
)
}, 0)
})
return this.appService.getHello()
}
}
[Nest] 141168 - 02/01/2022, 11:33:11 PM LOG [NestFactory] Starting Nest application...
[Nest] 141168 - 02/01/2022, 11:33:11 PM LOG [InstanceLoader] AsyncContextModule dependencies initialized +47ms
[Nest] 141168 - 02/01/2022, 11:33:11 PM LOG [InstanceLoader] AppModule dependencies initialized +1ms
[Nest] 141168 - 02/01/2022, 11:33:11 PM LOG [RoutesResolver] AppController {/}: +12ms
[Nest] 141168 - 02/01/2022, 11:33:11 PM LOG [RouterExplorer] Mapped {/, GET} route +7ms
[Nest] 141168 - 02/01/2022, 11:33:11 PM LOG [NestApplication] Nest application successfully started +5ms
[Nest] 141168 - 02/01/2022, 11:33:13 PM LOG [7398d3ad-c246-4650-8dd0-f8f29238bdd7] AppController.getHello
[Nest] 141168 - 02/01/2022, 11:33:13 PM LOG [7398d3ad-c246-4650-8dd0-f8f29238bdd7] AppController.getHello -> nextTick
[Nest] 141168 - 02/01/2022, 11:33:13 PM LOG [7398d3ad-c246-4650-8dd0-f8f29238bdd7] AppController.getHello -> nextTick -> setTimeout
AsyncContext
almost identical to native Map
objectclass AsyncContext {
// Clear all values from storage
clear(): void;
// Delete value by key from storage
delete(key: K): boolean;
// Iterate over storage
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
// Get value from storage by key
get(key: K): V | undefined;
// Check if key exists in storage
has(key: K): boolean;
// Set value by key in storage
set(key: K, value: V): this;
// Get number of keys that stored in storage
get size: number;
// Register context, it's better to use this method inside the interceptor
register(): void
// Register context for a callback, it's better to use this inside the middleware
registerCallback<R, TArgs extends any[]>(callback: (...args: TArgs) => R, ...args: TArgs): R
// Unregister context
unregister(): void
}
AsyncContextModule
interface AsyncContextModuleOptions {
// Should register this module as global, default: true
isGlobal?: boolean
// In case if you need to provide custom value AsyncLocalStorage
alsInstance?: AsyncLocalStorage<any>
}
class AsyncContextModule {
static forRoot (options?: AsyncContextModuleOptions): DynamicModule
}
You need to replace AsyncHooksModule
by AsyncContextModule.forRoot()
FAQs
NestJS Async Context based on async_hooks
The npm package @nestjs-steroids/async-context receives a total of 6,005 weekly downloads. As such, @nestjs-steroids/async-context popularity was classified as popular.
We found that @nestjs-steroids/async-context demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.