npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@anomira/node-sdk

v0.1.7

Published

Anomira Node.js SDK — drop-in API security monitoring for Express and Fastify

Readme

@anomira/node-sdk

Drop-in API security monitoring for Node.js. Detect brute force, credential stuffing, account takeover, data scraping, path traversal, XSS, geo-velocity attacks, and more — in real time.

Install

npm install @anomira/node-sdk

Quick Start

import { Anomira } from "@anomira/node-sdk";

const sentinel = new Anomira({
  apiKey:    process.env.SENTINEL_API_KEY,
  appId:     process.env.SENTINEL_APP_ID,
  ingestUrl: process.env.SENTINEL_INGEST_URL,
  debug:     true,
});

Express

import express from "express";
import { Anomira } from "@anomira/node-sdk";

const app = express();

const sentinel = new Anomira({
  apiKey:    process.env.SENTINEL_API_KEY,
  appId:     process.env.SENTINEL_APP_ID,
  ingestUrl: process.env.SENTINEL_INGEST_URL,
  debug:     true,
  captureConsole: true,   // forwards console.log/warn/error to Logs dashboard
  service:        "my-api",
  detect: {
    bruteForce:    true,
    rateAbuse:     true,
    pathTraversal: true,
    xss:           true,
    scanDetection: true,
    geoVelocity:   true,
  },
});

app.use(express.json());
app.use(sentinel.express());  // auto-instruments all routes

app.listen(3000);

Fastify

import Fastify from "fastify";
import { Anomira } from "@anomira/node-sdk";

const app = Fastify();

const sentinel = new Anomira({
  apiKey:    process.env.SENTINEL_API_KEY,
  appId:     process.env.SENTINEL_APP_ID,
  ingestUrl: process.env.SENTINEL_INGEST_URL,
});

await app.register(sentinel.fastify());

app.listen({ port: 3000 });

Manual Event Tracking

// Track a failed OTP attempt
sentinel.track("auth.otp.failed", {
  ip:     req.ip,
  userId: req.body.phone,
  meta:   { endpoint: "/api/verify-otp" },
});

// Track a login and run geo-velocity check automatically
await sentinel.trackLogin({ ip: req.ip, userId: user.id });

// Track phone-based auth (SIM swap detection)
sentinel.trackPhoneAuth({ ip: req.ip, userId: user.id, phone: user.phone });

Structured Logging

sentinel.log("info",  "User registered",   { userId: user.id });
sentinel.log("warn",  "Slow DB query",      { queryMs: 1240 });
sentinel.log("error", "Payment failed",     { reason: err.message });

Blocklist & Firewall

The SDK syncs your blocklist and firewall rules from the dashboard every 60 seconds. Check them in your own middleware:

if (sentinel.isBlocked(req.ip)) {
  return res.status(403).json({ error: "Forbidden" });
}

const match = sentinel.matchFirewallRule({
  url:     req.url,
  body:    req.body,
  headers: req.headers,
  ip:      req.ip,
});
if (match?.rule.action === "block") {
  return res.status(403).json({ error: "Blocked by firewall rule" });
}

Shadow Endpoint Detection

Register your known API routes on startup so Anomira can flag any undeclared endpoint that appears in live traffic. Endpoints that receive requests but were never declared show up in the API Surface Map as shadow endpoints.

// Call once after your routes are registered
await sentinel.declareEndpoints([
  { method: "POST", path: "/api/auth/login",           auth: false },
  { method: "POST", path: "/api/auth/register",        auth: false },
  { method: "GET",  path: "/api/users/:id",            auth: true  },
  { method: "GET",  path: "/api/orders",               auth: true  },
  { method: "POST", path: "/api/orders",               auth: true  },
  { method: "GET",  path: "/api/health",               auth: false },
]);

Express-style :param segments are normalized automatically — /users/:id and /users/:userId both map to /users/{id} to match discovered traffic.

Use auth: false for public endpoints. Authenticated endpoints default to auth: true.

Shadow detection from declared endpoints only activates once your org has registered at least one endpoint, so it won't produce noise on fresh deployments before you call this method.

Secret Scanner CLI

Scan your codebase for hardcoded secrets, API keys, BVN/NIN numbers, and PII before they reach production.

Uses three detection layers:

  • secretlint — 50+ service-specific rules (AWS, GCP, GitHub, Stripe, Slack, Twilio, SendGrid, PostgreSQL connection strings, and more)
  • Custom patterns — Nigerian PII (BVN/NIN), card PANs, phone numbers
  • Entropy analysis (--strict) — catches unknown high-entropy secrets with no known prefix, using Shannon entropy scoring

Run without installing:

npx @anomira/node-sdk scan ./src

If @anomira/node-sdk is already installed in your project:

npx anomira scan ./src

Options:

npx @anomira/node-sdk scan ./src           # scan a directory
npx @anomira/node-sdk scan .               # scan entire project
npx @anomira/node-sdk scan ./src --strict  # enable entropy analysis (catches unknown secrets)
npx @anomira/node-sdk scan ./src --json    # machine-readable JSON output for CI
npx @anomira/node-sdk scan ./src --quiet   # only print violations, no header

What it detects:

| Category | Examples | |---|---| | Cloud credentials | AWS access keys, GCP service account keys, Azure connection strings | | Source control | GitHub tokens (ghp_), GitLab tokens (glpat-), NPM tokens (npm_) | | Payment | Stripe keys (sk_live_), Paystack keys | | Communication | Slack tokens (xoxb-), Twilio credentials, SendGrid keys | | Database | Connection strings with embedded passwords (postgresql://user:pass@host) | | Auth | JWT tokens, generic API keys and bearer tokens | | Nigerian PII | BVN/NIN (11-digit), card PANs, Nigerian phone numbers | | Unknown secrets | High-entropy strings assigned to secret-like variables (--strict) |

Add to package.json for CI/CD:

{
  "scripts": {
    "scan": "anomira scan ./src --json"
  }
}

Exit code 0 = clean. Exit code 1 = violations found — use in CI to fail the build on leaked secrets.

Environment Variables

| Variable | Description | |---|---| | SENTINEL_API_KEY | Your Anomira API key | | SENTINEL_APP_ID | Your Anomira app ID | | SENTINEL_INGEST_URL | Ingest endpoint (from your dashboard) |

Configuration

| Option | Type | Default | Description | |---|---|---|---| | apiKey | string | — | Your Anomira API key (required) | | appId | string | — | Your Anomira app ID (required) | | ingestUrl | string | Anomira cloud | Ingest endpoint URL | | debug | boolean | false | Log SDK activity to console | | captureConsole | boolean | false | Forward console.* calls to the Logs dashboard | | service | string | "app" | Service name tag for logs | | detect.bruteForce | boolean | true | Detect brute force login attempts | | detect.rateAbuse | boolean | true | Detect rate limit abuse | | detect.pathTraversal | boolean | true | Detect path traversal attempts | | detect.xss | boolean | true | Detect XSS in request bodies | | detect.scanDetection | boolean | true | Detect scanner/bot probing | | detect.geoVelocity | boolean | true | Detect impossible travel between logins |

Graceful Shutdown

Always flush pending events before your process exits:

process.on("SIGTERM", async () => {
  await sentinel.flush();
  process.exit(0);
});

License

MIT