@coe-sys/pims
v1.0.1
Published
The shared NestJS support library behind the PIMS gateways: API-key auth, the proxy middlewares, request/response logging with redaction, and the process safety nets.
Readme
@coe-sys/pims
The shared NestJS support library behind the PIMS gateways: API-key auth, the proxy middlewares, request/response logging with redaction, and the process safety nets.
Install
npm install @coe-sys/pimsRequires NestJS ^11 and Node >= 20. The @nestjs/* packages are peer
dependencies, so npm will refuse the install on NestJS 10 rather than nest a
second framework copy. Do not force it onto NestJS 10 — a root-entry import
then fails to boot with a MongooseCoreModule/ModuleRef error. Services still
on 10 can use @coe-sys/pims/core (below) in the meantime; see the 0.8.0 notes
in CHANGELOG.md.
Quickstart
import { Module } from '@nestjs/common';
import { PimsModule } from '@coe-sys/pims';
@Module({ imports: [PimsModule] })
export class AppModule {}PimsModule needs MONGODB_URI in the environment, and reads API_LOG,
KAFKA_LOG, GATEWAY_HOST and GATEWAY_KEY for the logging paths. It exports
PimsService, LogService, ApiKeysService, ResponseInterceptorService and
ApiLogInterceptor.
Customising what gets logged
LOG_POLICY decides which requests are logged and how they are redacted. The
default (DefaultLogPolicy) excludes credential and payment routes and masks
sensitive headers. Replace it through forRoot:
import { Module } from '@nestjs/common';
import { PimsModule, DefaultLogPolicy, LogRequestContext } from '@coe-sys/pims';
/** Keep payment traffic, but store the response as an audit marker only. */
class PaymentAuditLogPolicy extends DefaultLogPolicy {
shouldLog(ctx: LogRequestContext): boolean {
return /\/payment\//i.test(ctx.uri) || super.shouldLog(ctx);
}
redactResponse(): unknown {
return '[AUDITED]';
}
}
@Module({
imports: [PimsModule.forRoot({ logPolicy: PaymentAuditLogPolicy })],
})
export class AppModule {}Use forRoot — not providers: [{ provide: LOG_POLICY, ... }] in your own
module. Nest resolves providers per module, so a provider declared in your
AppModule cannot shadow the one inside PimsModule: your APP_INTERCEPTOR-built
ApiLogInterceptor would use your policy while the library's own writers kept
the default, redacting the same request two different ways. forRoot replaces
the provider inside PimsModule, which reaches all three writers.
Policy methods must be synchronous and must not throw — they run on the proxy response path.
@coe-sys/pims/core
The framework-free subset: no @nestjs/*, no mongoose, no
http-proxy-middleware is pulled into the process. Importable from any NestJS
version, or from an application that uses no framework at all.
import { shouldLogUri, redactBody, hashApiKey, convertKsqlResult } from '@coe-sys/pims/core';Process safety nets
Node terminates on an unhandled rejection or uncaught exception by default, and this library floats promises that reach Mongo. Install the nets once at bootstrap so a Mongo hiccup becomes a logged incident instead of downtime:
import { installProcessSafetyNets } from '@coe-sys/pims';
installProcessSafetyNets();Pair it with a container restart policy and alerting on those log lines.
Changelog
See CHANGELOG.md — including the breaking changes in 1.0.0.
