@qbobjx/nestjs
v0.3.0
Published
Official NestJS integration for OBJX.
Readme
@qbobjx/nestjs
Official NestJS integration for OBJX.
Install
npm install @qbobjx/nestjs @nestjs/common @nestjs/core rxjsAdd your driver and core packages as needed, for example:
npm install @qbobjx/core @qbobjx/sqlite-driver @qbobjx/pluginsWhat You Get
ObjxModule.forRoot(...)ObjxModule.forRootAsync(...)- session injection token and
@InjectObjxSession()helper ObjxSessionHost<TSession>service for a typed session host without custom decorators everywhereInferObjxSession<typeof yourFactory>helper type- optional request-scoped execution context middleware/interceptor
- global exception filter support for OBJX validation errors
Quick Usage
import { Module } from '@nestjs/common';
import { ObjxModule } from '@qbobjx/nestjs';
@Module({
imports: [
ObjxModule.forRootAsync({
global: true,
useFactory: async () => ({
session: createSessionSomehow(),
}),
}),
],
})
export class AppModule {}Recommended Typing Pattern
If you do not want ReturnType<typeof createSqliteSession> repeated across services, infer the
session type once from your module options factory and inject ObjxSessionHost<TSession>:
import { Injectable } from '@nestjs/common';
import { InferObjxSession, ObjxSessionHost } from '@qbobjx/nestjs';
export function createObjxNestModuleOptions() {
return {
session: createSessionSomehow(),
};
}
export type AppObjxSession = InferObjxSession<typeof createObjxNestModuleOptions>;
@Injectable()
export class ProjectsService {
constructor(private readonly objx: ObjxSessionHost<AppObjxSession>) {}
listProjects() {
return this.objx.session.execute(Project.query());
}
}Use @InjectObjxSession() when you only want the bare session. Use ObjxSessionHost<TSession> when
you want the typed session plus helper access to the current execution context.
Postgres RLS With Request Context
If your NestJS app uses PostgreSQL RLS with current_setting(...), configure the Postgres session
to project request-context values into set_config(...) at transaction start:
import { createExecutionContextManager } from '@qbobjx/core';
import { createPostgresSession } from '@qbobjx/postgres-driver';
const executionContextManager = createExecutionContextManager();
const session = createPostgresSession({
pool,
executionContextManager,
executionContextSettings: {
bindings: [
{ setting: 'app.tenant_id', contextKey: 'tenantId', required: true },
{ setting: 'app.actor_id', contextKey: 'actorId' },
],
},
});With ObjxModule request context enabled, headers like x-tenant-id and x-actor-id already flow
into the execution context. To make PostgreSQL RLS see them, run the protected work inside
session.transaction(...) so OBJX can apply the set_config(...) bindings on the same connection.
