![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
nestjs-context
Advanced tools
Nestjs execution context information service including request scoped info
NestJs (request-scoped) context to access execution-context-request information everywhere
This project includes:
import { Module, Logger } from '@nestjs/common';
import { ContextModule } from 'nesjs-context';
import { GetUser } from './context-providers';
@Module({
imports: [
ContextModule.register(),
],
})
export class ExampleModule {}
import { Module, Logger } from '@nestjs/common';
import { ContextModule } from 'nesjs-context';
import { GetUser } from './context-providers';
@Module({
imports: [
ContextModule.register({
cached: true, // false by default; the values are calculated only once per request
useDefaults: true, // true by default; adds useful defaults to the context
type: ContextName.HTTP, // Http by default
build: { // empty by default
host: ['localhost', 'req.headers.host'], // request path with fallback to "localhost"
node_env: [process.env.NODE_ENV], // value
entity: [(req: Request) => `${req.params.entity}_${req.params.id}`], // callback
},
}),
],
})
export class ExampleModule {}
The context object uses the "build" definition from the config to pick elements from the request. That is an object where the keys are the resulting context properties, and the values are LIFO of possible values for that property. A value can be defined using:
** It is a special case - see Context with Dependency injection for examples
As possible values are LIFO, if the last value was null or undefined the context will try with the previous one, and so successively. You can manually set values into context calling "Context::setCachedValue": set values will take precedence over any other declared possible values.
The simplest way to add a property provider in your context is passing the "providers" to the context module. Notice that you will also need to pass its dependencies too:
@Module({
imports: [
ContextModule.register({
type: ContextName.HTTP,
build: {
value: ['inside-imported'],
provided: [PropertyProvider],
},
// as PropertyProviders depends on PropertyProviderService, we pass both providers
providers: [PropertyProvider, PropertyProviderService],
}),
],
controllers: [ImportedController],
providers: [ImportedService],
exports: [ImportedService],
})
export class ExampleModule {}
You could also pass "imports" to get all the exported providers from the given modules:
@Module({
imports: [
ContextModule.register({
type: ContextName.HTTP,
build: {
value: ['inside-imported'],
provided: [PropertyProvider],
},
providers: [PropertyProvider],
// as PropertyProviders depends on MyModule, we pass the module too
imports: [MyModule.register()]
}),
],
controllers: [ImportedController],
providers: [ImportedService],
exports: [ImportedService],
})
export class ExampleModule {}
It can be tedious to pass every dependency to the context. Especially at the application level, where you may be adding the same dependencies to the context module and to the application main module. To reduce the boilerplate, we can convert our app to be a ContextModule itself, so the ModuleRef of the Context will be the same as the main module:
import {ContextConfigType} from "./context-config.type";
const contextConfig: ContextConfigType = {
type: ContextName.HTTP,
build: {
host: ['req.headers.host'], // request path
node_env: [process.env.NODE_ENV], // value
entity: [(req: Request) => `${req.params.entity}_${req.params.id}`], // callback
user: ['anon.', GetUser], // provider with fallback to "anon."
},
};
@Module({})
export class ExampleModule {
static register() {
return convertToContextModule(
{
providers: [ExampleProvider, GetUser],
imports: [ImportedModule],
controllers: [ExampleController],
},
contextConfig,
);
}
}
Be careful: by default, "convertToContextModule" will set your module name to "ContextModule", if you are using it for a module that is not the main module of the application, it could cause your module to be ignored -in the case there is another context module that is being loaded before-. If you want to keep your module name instead and to keep unique context for your application, you must specify it explicitly:
@Module({})
export class ExampleModule {
static register() {
return {
...convertToContextModule(
{
providers: [ExampleProvider, GetUser],
imports: [ImportedModule],
controllers: [ExampleController],
},
contextConfig,
),
module: ExampleModule
};
}
}
If you need to include a correlation_id in your context, even if the x-correlation-id header is not included, you can use a correlation_id generator as callback:
Notice that everytime we have a Context::correlation_id, it will be included in the http response headers.
import { Module, Logger } from '@nestjs/common';
import { ContextModule } from 'nesjs-context';
import { GetUser } from './context-providers';
@Module({
imports: [
ContextModule.registerWithDefaults({
type: ContextName.HTTP,
build: {},
correlation_id: {
//header: 'my-header', // use "my-header" instead of X-Correlation-Id as reference header
generator: true // there is a default correlation_id generator inside the module
// generator: (req) => 'generated-correlation-id' // but you can also use a custom one
},
}),
],
})
export class ExampleModule {}
import {CorrelationId, ContextAware} from 'nestjs-context';
@Injectable()
@ContextAware()
export class MyProvider {
@CorrelationId()
private declare readonly correlationId;
}
import { AddCorrelationId } from 'nestjs-context';
@Injectable()
@AddCorrelationId('property.correlation_id')
export class MyProvider {
private readonly property; // property.correlation_id will be created
}
You can use @BuildDto in your controllers to build a dto using different parts of the request at once. The decorator receives as an argument a definition with the same format as for the context construction (except for the provider definition, still not working -see WIP-):
export class ExampleController {
// if body.id is undefined or null, dto_id will be set to query.id;
// if both are null or undefined, it will be set to "EMPTY"
async example1(@BuildDto({dto_id: ['EMPTY', 'req.query.id', 'req.body.id']}) dto: ExampleDto) {
// your code
}
}
The previous example will only work for HTTP execution context, but there is another version of the call that allows us to:
export class ExampleController {
@Post('/example')
// This will try to build all the elements of ExampleDto from the body
// and then it will override "dto::child::id" with params.child_id, if it is defined
// and dto::id with params.id, if it is defined
async example(
@BuildDto({
target: ExampleDto,
type: ContextName.HTTP,
build: { "id": "req.params.id", "child.id": ['req.params.child_id'] },
auto: { enabled: true, path: 'body', is_fallback: true },
})
dto: ExampleDto,
) {
// your code
}
}
is_fallback: true
.@BuildDto needs you to configure tsconfig with useDefineForClassFields: true
or
strictPropertyInitialization: true
. Without any of those configs, any declared and not initialised
property in your DTO won't be taken into account when building the DTO
Create an issue.
FAQs
Nestjs execution context information service including request scoped info
The npm package nestjs-context receives a total of 440 weekly downloads. As such, nestjs-context popularity was classified as not popular.
We found that nestjs-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
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.