@arcane-utils/middlewares
v1.0.2
Published
Reusable Express middlewares for Arcane services.
Readme
@arcane-utils/middlewares
Reusable Express middlewares for Arcane services.
CHANGE LOG
V 1.0.2
Point @arcane-utils/pubsub at ^2.0.1
V 1.0.1
Security: move @arcane-utils/pubsub to 2.0.0, which uses @google-cloud/pubsub 6.0.1 instead of a version in the 0.20.0 - 3.7.5 vulnerable range (critical protobufjs prototype pollution and arbitrary code execution, plus @grpc/grpc-js and google-gax advisories) Security: sanitize control characters in LogTrackingAdapter, since function_name and origin come from the request path and the Origin header and could forge log lines Declare @google-cloud/pubsub as a peer dependency: it was imported by the pubsub adapter without being declared Update build/test tooling (typescript 5.9.3, tsup 8.5.1, ts-jest 29.4.12)
V 1.0.0
Init component with the tracking middleware.
Tracking Middleware
Per-request activity tracking: captures request metadata, allows incremental enrichment from anywhere in the async call chain, and publishes one normalized event per request to a configurable backend.
Setup
import {
createTrackingMiddleware,
PubSubTrackingAdapter,
enrichTracking,
} from '@arcane-utils/middlewares'
import { getPubsubClient } from '@arcane-utils/pubsub'
const pubsub = getPubsubClient('my-gcp-project', '/path/to/credentials.json')
const tracker = new PubSubTrackingAdapter(pubsub, {
project: 'my-gcp-project',
// topic: 'activity-tracker', // default
})
app.use(
createTrackingMiddleware(tracker, 'my-service', {
excludedEndpoints: [/^\/health/, /^\/ready/],
onError: (err) => console.error('Tracking error', err),
})
)Enriching events from handlers
Call enrichTracking() from anywhere in the async call chain — no need to pass req:
import { enrichTracking } from '@arcane-utils/middlewares'
app.get('/campaigns/:id', async (req, res) => {
enrichTracking({ user_email: req.user.email, additional_info: { campaign_id: req.params.id } })
// business logic...
})Using the log adapter (local/dev)
import { LogTrackingAdapter } from '@arcane-utils/middlewares'
import { logger } from '@arcane-utils/logger'
const tracker = new LogTrackingAdapter(logger)
app.use(createTrackingMiddleware(tracker, 'my-service'))Event shape
| Field | Type | Description |
|---|---|---|
| user_email | string | User identity (empty until auth layer added) |
| service | string | Service name passed to middleware |
| function_name | string | req.path, overridable via enrichTracking |
| origin | string | Origin request header |
| status_code | number | HTTP response status code |
| execution_time | number | Request duration in seconds |
| timestamp | string | ISO 8601 UTC |
| insert_id | string | UUID v4, unique per event |
| additional_info | Record<string, unknown> | Optional free-form metadata |
Adding a new middleware capability
Add a new subfolder under src/:
src/
auth/
index.ts
...Then add one line to src/index.ts:
export * from './auth'