@anomira/node-sdk 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,9 +11,9 @@ npm install @anomira/node-sdk
11
11
  ## Quick Start
12
12
 
13
13
  ```js
14
- import { SentinelAPI } from "@anomira/node-sdk";
14
+ import { Anomira } from "@anomira/node-sdk";
15
15
 
16
- const sentinel = new SentinelAPI({
16
+ const sentinel = new Anomira({
17
17
  apiKey: process.env.SENTINEL_API_KEY,
18
18
  appId: process.env.SENTINEL_APP_ID,
19
19
  ingestUrl: process.env.SENTINEL_INGEST_URL,
@@ -25,11 +25,11 @@ const sentinel = new SentinelAPI({
25
25
 
26
26
  ```js
27
27
  import express from "express";
28
- import { SentinelAPI } from "@anomira/node-sdk";
28
+ import { Anomira } from "@anomira/node-sdk";
29
29
 
30
30
  const app = express();
31
31
 
32
- const sentinel = new SentinelAPI({
32
+ const sentinel = new Anomira({
33
33
  apiKey: process.env.SENTINEL_API_KEY,
34
34
  appId: process.env.SENTINEL_APP_ID,
35
35
  ingestUrl: process.env.SENTINEL_INGEST_URL,
@@ -56,11 +56,11 @@ app.listen(3000);
56
56
 
57
57
  ```js
58
58
  import Fastify from "fastify";
59
- import { SentinelAPI } from "@anomira/node-sdk";
59
+ import { Anomira } from "@anomira/node-sdk";
60
60
 
61
61
  const app = Fastify();
62
62
 
63
- const sentinel = new SentinelAPI({
63
+ const sentinel = new Anomira({
64
64
  apiKey: process.env.SENTINEL_API_KEY,
65
65
  appId: process.env.SENTINEL_APP_ID,
66
66
  ingestUrl: process.env.SENTINEL_INGEST_URL,
@@ -116,6 +116,28 @@ if (match?.rule.action === "block") {
116
116
  }
117
117
  ```
118
118
 
119
+ ## Shadow Endpoint Detection
120
+
121
+ 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.
122
+
123
+ ```js
124
+ // Call once after your routes are registered
125
+ await sentinel.declareEndpoints([
126
+ { method: "POST", path: "/api/auth/login", auth: false },
127
+ { method: "POST", path: "/api/auth/register", auth: false },
128
+ { method: "GET", path: "/api/users/:id", auth: true },
129
+ { method: "GET", path: "/api/orders", auth: true },
130
+ { method: "POST", path: "/api/orders", auth: true },
131
+ { method: "GET", path: "/api/health", auth: false },
132
+ ]);
133
+ ```
134
+
135
+ Express-style `:param` segments are normalized automatically — `/users/:id` and `/users/:userId` both map to `/users/{id}` to match discovered traffic.
136
+
137
+ Use `auth: false` for public endpoints. Authenticated endpoints default to `auth: true`.
138
+
139
+ 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.
140
+
119
141
  ## Secret Scanner CLI
120
142
 
121
143
  Scan your codebase for hardcoded secrets, API keys, BVN/NIN numbers, and PII before they reach production.
package/dist/cli.cjs CHANGED
@@ -5606,17 +5606,15 @@ var creator = {
5606
5606
 
5607
5607
  // src/sensitive.ts
5608
5608
  var PATTERNS = [
5609
- // ── Cryptographic keys and certificates ───────────────────────────────────
5609
+ // ── Cryptographic private keys ────────────────────────────────────────────
5610
+ // NOTE: -----BEGIN CERTIFICATE----- is intentionally excluded — public
5611
+ // certificates are designed to be public and committing them is correct.
5612
+ // Only PRIVATE keys are dangerous.
5610
5613
  {
5611
5614
  type: "private_key",
5612
5615
  label: "Private Key",
5613
5616
  regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/
5614
5617
  },
5615
- {
5616
- type: "certificate",
5617
- label: "Certificate / Public Key",
5618
- regex: /-----BEGIN CERTIFICATE-----/
5619
- },
5620
5618
  // ── Cloud provider credentials ────────────────────────────────────────────
5621
5619
  {
5622
5620
  // AWS access key ID — highly specific, almost no false positives
@@ -5731,26 +5729,30 @@ var PATTERNS = [
5731
5729
  regex: /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/
5732
5730
  },
5733
5731
  {
5734
- // Generic API key / token assigned to a keyword (must have 20+ char value)
5732
+ // Generic API key / token only flag QUOTED literals, not variable/env references.
5733
+ // Skips: api_key = process.env.KEY, token = myVar
5734
+ // Matches: api_key = "sk-abc123...", bearer: "eyJhb..."
5735
5735
  type: "api_key",
5736
5736
  label: "API Key / Token",
5737
- regex: /\b(?:api[_-]?key|access[_-]?token|auth[_-]?token|bearer|client[_-]?secret)\s*[:=]\s*["']?[A-Za-z0-9_.\/+\-]{20,}["']?/i
5737
+ regex: /\b(?:api[_-]?key|access[_-]?token|auth[_-]?token|bearer|client[_-]?secret)\s*[:=]\s*["'][A-Za-z0-9_.\/+\-]{20,}["']/i
5738
5738
  },
5739
5739
  // ── Password fields ───────────────────────────────────────────────────────
5740
5740
  {
5741
- // Password/secret keyword immediately followed by a non-placeholder value
5742
- // Avoids false positives on "password: ${PASSWORD}" or "password: xxxx"
5741
+ // Only flag QUOTED string literals after a password/secret keyword.
5742
+ // Skips: process.env.*, variable references, undefined/null, template literals.
5743
+ // Matches: password: "hunter2", secret: 'abc123def', pass="hardcoded!"
5743
5744
  type: "password",
5744
- label: "Password / Secret",
5745
- regex: /\b(?:password|passwd|pwd|pass|secret|credentials?)\s*[:=]\s*["']?(?!\$\{)[^\s"'$]{6,}["']?/i
5745
+ label: "Hardcoded Password",
5746
+ regex: /\b(?:password|passwd|pwd|pass|secret|credentials?)\s*[:=]\s*["'][^"'$\s]{6,}["']/i
5746
5747
  },
5747
5748
  // ── Nigeria-specific PII ──────────────────────────────────────────────────
5748
5749
  {
5749
- // BVN / NIN: 11 digits, first digit 1-9 (not a phone starting with 0)
5750
- // Require a non-digit boundary on both sides to reduce false positives
5750
+ // BVN / NIN: 11 digits, first digit 1-9 (not a phone number starting with 0)
5751
+ // Exclude: inside URLs (preceded by / : @ - %), hex strings (followed by a-f),
5752
+ // and UUIDs/hashes (surrounded by alphanumeric chars)
5751
5753
  type: "bvn",
5752
5754
  label: "BVN / NIN",
5753
- regex: /(?<!\d)[1-9]\d{10}(?!\d)/
5755
+ regex: /(?<![/\-:@%=a-fA-F\w])[1-9]\d{10}(?![a-fA-F\d])/
5754
5756
  },
5755
5757
  {
5756
5758
  // Nigerian phone numbers: 080x, 081x, 070x, 090x, 091x — or with +234 prefix
@@ -5843,8 +5845,28 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
5843
5845
  ".turbo",
5844
5846
  ".cache",
5845
5847
  "tmp",
5846
- "temp"
5848
+ "temp",
5849
+ // Test directories — skipped by default, use --include-tests to scan them
5850
+ "tests",
5851
+ "test",
5852
+ "__tests__",
5853
+ "spec",
5854
+ "__spec__",
5855
+ "fixtures",
5856
+ "__fixtures__",
5857
+ "mocks",
5858
+ "__mocks__"
5847
5859
  ]);
5860
+ var TEST_FILE_PATTERNS = [
5861
+ ".test.js",
5862
+ ".test.ts",
5863
+ ".test.jsx",
5864
+ ".test.tsx",
5865
+ ".spec.js",
5866
+ ".spec.ts",
5867
+ ".spec.jsx",
5868
+ ".spec.tsx"
5869
+ ];
5848
5870
  function shannonEntropy(str) {
5849
5871
  const freq = {};
5850
5872
  for (const ch of str) freq[ch] = (freq[ch] ?? 0) + 1;
@@ -5876,7 +5898,12 @@ var SECRETLINT_CONFIG = {
5876
5898
  }
5877
5899
  ]
5878
5900
  };
5879
- function shouldScan(filePath) {
5901
+ function isTestFile(filePath) {
5902
+ const base = path2__default.default.basename(filePath);
5903
+ return TEST_FILE_PATTERNS.some((p) => base.endsWith(p));
5904
+ }
5905
+ function shouldScan(filePath, includeTests) {
5906
+ if (!includeTests && isTestFile(filePath)) return false;
5880
5907
  const ext = path2__default.default.extname(filePath);
5881
5908
  const base = path2__default.default.basename(filePath);
5882
5909
  if (base.startsWith(".env")) return true;
@@ -5957,14 +5984,14 @@ async function scanFile(filePath, strict) {
5957
5984
  }
5958
5985
  return violations;
5959
5986
  }
5960
- function* walkDir(dir) {
5987
+ function* walkDir(dir, includeTests) {
5961
5988
  const entries = fs__default.default.readdirSync(dir, { withFileTypes: true });
5962
5989
  for (const entry of entries) {
5963
5990
  if (SKIP_DIRS.has(entry.name)) continue;
5964
5991
  const full = path2__default.default.join(dir, entry.name);
5965
5992
  if (entry.isDirectory()) {
5966
- yield* walkDir(full);
5967
- } else if (entry.isFile() && shouldScan(full)) {
5993
+ yield* walkDir(full, includeTests);
5994
+ } else if (entry.isFile() && shouldScan(full, includeTests)) {
5968
5995
  yield full;
5969
5996
  }
5970
5997
  }
@@ -5976,6 +6003,7 @@ async function main() {
5976
6003
  const quiet = args.includes("--quiet") || args.includes("-q");
5977
6004
  const jsonOut = args.includes("--json");
5978
6005
  const strict = args.includes("--strict");
6006
+ const includeTests = args.includes("--include-tests");
5979
6007
  if (args.includes("--help") || args.includes("-h") || args[0] === "help") {
5980
6008
  console.log(`
5981
6009
  ${c.bold}Anomira Secret Scanner${c.reset}
@@ -5989,10 +6017,11 @@ Detection layers:
5989
6017
  Layer 3 Entropy \u2014 High-entropy string detection (--strict only)
5990
6018
 
5991
6019
  Options:
5992
- --strict Enable entropy analysis (catches unknown secrets, more noise)
5993
- --quiet, -q Only print violations (suppress summary header)
5994
- --json Machine-readable JSON output (for CI pipelines)
5995
- --help, -h Show this help
6020
+ --strict Enable entropy analysis (catches unknown secrets, more noise)
6021
+ --include-tests Also scan test files (*.test.*, *.spec.*, tests/ dirs \u2014 skipped by default)
6022
+ --quiet, -q Only print violations (suppress summary header)
6023
+ --json Machine-readable JSON output (for CI pipelines)
6024
+ --help, -h Show this help
5996
6025
 
5997
6026
  Examples:
5998
6027
  npx @anomira/node-sdk scan ./src
@@ -6016,7 +6045,7 @@ ${c.bold}${c.cyan}Anomira Secret Scanner${c.reset}`);
6016
6045
  console.log(`${c.grey}Layers: secretlint + custom patterns${strict ? " + entropy" : ""}${c.reset}
6017
6046
  `);
6018
6047
  }
6019
- const files = fs__default.default.statSync(target).isDirectory() ? [...walkDir(target)] : [target];
6048
+ const files = fs__default.default.statSync(target).isDirectory() ? [...walkDir(target, includeTests)] : [target];
6020
6049
  const allViolations = [];
6021
6050
  let fileCount = 0;
6022
6051
  for (const file of files) {
package/dist/index.cjs CHANGED
@@ -109,10 +109,10 @@ var EventBuffer = class {
109
109
  }
110
110
  }
111
111
  log(...args) {
112
- if (this.opts.debug) console.log("[SentinelAPI]", ...args);
112
+ if (this.opts.debug) console.log("[Anomira]", ...args);
113
113
  }
114
114
  warn(...args) {
115
- console.warn("[SentinelAPI]", ...args);
115
+ console.warn("[Anomira]", ...args);
116
116
  }
117
117
  };
118
118
  function sleep(ms) {
@@ -199,17 +199,15 @@ async function checkGeoVelocity(userId, ip, tsMs, lookupUrl) {
199
199
 
200
200
  // src/sensitive.ts
201
201
  var PATTERNS = [
202
- // ── Cryptographic keys and certificates ───────────────────────────────────
202
+ // ── Cryptographic private keys ────────────────────────────────────────────
203
+ // NOTE: -----BEGIN CERTIFICATE----- is intentionally excluded — public
204
+ // certificates are designed to be public and committing them is correct.
205
+ // Only PRIVATE keys are dangerous.
203
206
  {
204
207
  type: "private_key",
205
208
  label: "Private Key",
206
209
  regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/
207
210
  },
208
- {
209
- type: "certificate",
210
- label: "Certificate / Public Key",
211
- regex: /-----BEGIN CERTIFICATE-----/
212
- },
213
211
  // ── Cloud provider credentials ────────────────────────────────────────────
214
212
  {
215
213
  // AWS access key ID — highly specific, almost no false positives
@@ -324,26 +322,30 @@ var PATTERNS = [
324
322
  regex: /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/
325
323
  },
326
324
  {
327
- // Generic API key / token assigned to a keyword (must have 20+ char value)
325
+ // Generic API key / token only flag QUOTED literals, not variable/env references.
326
+ // Skips: api_key = process.env.KEY, token = myVar
327
+ // Matches: api_key = "sk-abc123...", bearer: "eyJhb..."
328
328
  type: "api_key",
329
329
  label: "API Key / Token",
330
- regex: /\b(?:api[_-]?key|access[_-]?token|auth[_-]?token|bearer|client[_-]?secret)\s*[:=]\s*["']?[A-Za-z0-9_.\/+\-]{20,}["']?/i
330
+ regex: /\b(?:api[_-]?key|access[_-]?token|auth[_-]?token|bearer|client[_-]?secret)\s*[:=]\s*["'][A-Za-z0-9_.\/+\-]{20,}["']/i
331
331
  },
332
332
  // ── Password fields ───────────────────────────────────────────────────────
333
333
  {
334
- // Password/secret keyword immediately followed by a non-placeholder value
335
- // Avoids false positives on "password: ${PASSWORD}" or "password: xxxx"
334
+ // Only flag QUOTED string literals after a password/secret keyword.
335
+ // Skips: process.env.*, variable references, undefined/null, template literals.
336
+ // Matches: password: "hunter2", secret: 'abc123def', pass="hardcoded!"
336
337
  type: "password",
337
- label: "Password / Secret",
338
- regex: /\b(?:password|passwd|pwd|pass|secret|credentials?)\s*[:=]\s*["']?(?!\$\{)[^\s"'$]{6,}["']?/i
338
+ label: "Hardcoded Password",
339
+ regex: /\b(?:password|passwd|pwd|pass|secret|credentials?)\s*[:=]\s*["'][^"'$\s]{6,}["']/i
339
340
  },
340
341
  // ── Nigeria-specific PII ──────────────────────────────────────────────────
341
342
  {
342
- // BVN / NIN: 11 digits, first digit 1-9 (not a phone starting with 0)
343
- // Require a non-digit boundary on both sides to reduce false positives
343
+ // BVN / NIN: 11 digits, first digit 1-9 (not a phone number starting with 0)
344
+ // Exclude: inside URLs (preceded by / : @ - %), hex strings (followed by a-f),
345
+ // and UUIDs/hashes (surrounded by alphanumeric chars)
344
346
  type: "bvn",
345
347
  label: "BVN / NIN",
346
- regex: /(?<!\d)[1-9]\d{10}(?!\d)/
348
+ regex: /(?<![/\-:@%=a-fA-F\w])[1-9]\d{10}(?![a-fA-F\d])/
347
349
  },
348
350
  {
349
351
  // Nigerian phone numbers: 080x, 081x, 070x, 090x, 091x — or with +234 prefix
@@ -410,7 +412,7 @@ var DEFAULT_INGEST_URL = "https://ingest.anomira.io/v1/events";
410
412
  var DEFAULT_BATCH_SIZE = 100;
411
413
  var DEFAULT_FLUSH_MS = 5e3;
412
414
  var DEFAULT_MAX_RETRIES = 3;
413
- var SentinelClient = class {
415
+ var AnomiraClient = class {
414
416
  constructor(config) {
415
417
  this.logBuffer = [];
416
418
  this.logFlushTimer = null;
@@ -509,7 +511,7 @@ var SentinelClient = class {
509
511
  console[method] = (...args) => {
510
512
  original(...args);
511
513
  const first = args[0];
512
- if (typeof first === "string" && first.startsWith("[SentinelAPI]")) return;
514
+ if (typeof first === "string" && first.startsWith("[Anomira]")) return;
513
515
  const message = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
514
516
  const ctx = requestContext.getStore();
515
517
  this.log(level, message, {
@@ -533,7 +535,7 @@ var SentinelClient = class {
533
535
  const data = await res.json();
534
536
  this.blockedIpCache = new Set(data.ips ?? []);
535
537
  if (this.config.debug && this.blockedIpCache.size > 0) {
536
- this._origLog(`[SentinelAPI] blocklist refreshed \u2014 ${this.blockedIpCache.size} blocked IPs`);
538
+ this._origLog(`[Anomira] blocklist refreshed \u2014 ${this.blockedIpCache.size} blocked IPs`);
537
539
  }
538
540
  } catch {
539
541
  }
@@ -561,7 +563,7 @@ var SentinelClient = class {
561
563
  })() : void 0
562
564
  }));
563
565
  if (this.config.debug && this.compiledRules.length > 0) {
564
- this._origLog(`[SentinelAPI] firewall rules refreshed \u2014 ${this.compiledRules.length} active rules`);
566
+ this._origLog(`[Anomira] firewall rules refreshed \u2014 ${this.compiledRules.length} active rules`);
565
567
  }
566
568
  } catch {
567
569
  }
@@ -612,7 +614,7 @@ var SentinelClient = class {
612
614
  signal: AbortSignal.timeout(8e3)
613
615
  });
614
616
  if (this.config.debug) {
615
- this._origLog(`[SentinelAPI] [logs] \u2705 sent ${batch.length} log entries (${res.status})`);
617
+ this._origLog(`[Anomira] [logs] \u2705 sent ${batch.length} log entries (${res.status})`);
616
618
  }
617
619
  } catch {
618
620
  this.logBuffer.unshift(...batch);
@@ -631,24 +633,24 @@ var SentinelClient = class {
631
633
  signal: AbortSignal.timeout(5e3)
632
634
  });
633
635
  if (res.status >= 300 && res.status < 400) {
634
- this._origWarn(`[SentinelAPI] \u274C Wrong ingest URL \u2014 got redirect to ${res.headers.get("location")}. Check SENTINEL_INGEST_URL.`);
636
+ this._origWarn(`[Anomira] \u274C Wrong ingest URL \u2014 got redirect to ${res.headers.get("location")}. Check SENTINEL_INGEST_URL.`);
635
637
  return;
636
638
  }
637
639
  if (res.ok) {
638
- this._origLog(`[SentinelAPI] \u2705 Connected (appId: ${this.config.appId.slice(0, 8)}\u2026)`);
640
+ this._origLog(`[Anomira] \u2705 Connected (appId: ${this.config.appId.slice(0, 8)}\u2026)`);
639
641
  return;
640
642
  }
641
643
  if (res.status === 401) {
642
- this._origWarn("[SentinelAPI] \u274C Invalid API key \u2014 check your SENTINEL_API_KEY");
644
+ this._origWarn("[Anomira] \u274C Invalid API key \u2014 check your SENTINEL_API_KEY");
643
645
  return;
644
646
  }
645
647
  if (res.status === 403) {
646
- this._origWarn("[SentinelAPI] \u274C App not found or appId mismatch \u2014 check your SENTINEL_APP_ID");
648
+ this._origWarn("[Anomira] \u274C App not found or appId mismatch \u2014 check your SENTINEL_APP_ID");
647
649
  return;
648
650
  }
649
- this._origWarn(`[SentinelAPI] \u26A0\uFE0F Ingest returned HTTP ${res.status} \u2014 check your configuration`);
651
+ this._origWarn(`[Anomira] \u26A0\uFE0F Ingest returned HTTP ${res.status} \u2014 check your configuration`);
650
652
  } catch {
651
- this._origWarn("[SentinelAPI] \u26A0\uFE0F Could not reach ingest endpoint \u2014 check SENTINEL_INGEST_URL (current: " + this.config.ingestUrl + ")");
653
+ this._origWarn("[Anomira] \u26A0\uFE0F Could not reach ingest endpoint \u2014 check SENTINEL_INGEST_URL (current: " + this.config.ingestUrl + ")");
652
654
  }
653
655
  }
654
656
  // ─── Public API ────────────────────────────────────────────────────────────
@@ -745,7 +747,7 @@ var SentinelClient = class {
745
747
  });
746
748
  }
747
749
  /**
748
- * Send a structured log entry to the SentinelAPI Logs dashboard.
750
+ * Send a structured log entry to the Anomira Logs dashboard.
749
751
  *
750
752
  * ```ts
751
753
  * sentinel.log("info", "User registered", { userId: user.id });
@@ -761,16 +763,47 @@ var SentinelClient = class {
761
763
  rest["sensitiveLeaks"] = leaks.map((l) => l.type);
762
764
  if (this.config.debug) {
763
765
  this._origWarn(
764
- `[SentinelAPI] \u26A0\uFE0F Sensitive data in log (${leaks.map((l) => l.label).join(", ")}): "${message.slice(0, 60)}\u2026"`
766
+ `[Anomira] \u26A0\uFE0F Sensitive data in log (${leaks.map((l) => l.label).join(", ")}): "${message.slice(0, 60)}\u2026"`
765
767
  );
766
768
  }
767
769
  }
768
770
  this.logBuffer.push({ level, service: service ?? this.config.service, message, meta: rest, ts: Date.now() });
769
771
  if (this.config.debug && leaks.length === 0) {
770
- this._origLog(`[SentinelAPI] log:${level} ${message}`);
772
+ this._origLog(`[Anomira] log:${level} ${message}`);
771
773
  }
772
774
  if (this.logBuffer.length >= 50) void this.#flushLogs();
773
775
  }
776
+ /**
777
+ * Declare your API's known endpoints so Anomira can flag undiscovered
778
+ * traffic as shadow endpoints.
779
+ *
780
+ * Call this once on startup after your routes are registered:
781
+ *
782
+ * ```ts
783
+ * await sentinel.declareEndpoints([
784
+ * { method: "GET", path: "/api/users/:id", auth: true },
785
+ * { method: "POST", path: "/api/orders", auth: true },
786
+ * { method: "GET", path: "/api/health", auth: false },
787
+ * ]);
788
+ * ```
789
+ */
790
+ async declareEndpoints(endpoints) {
791
+ if (this.disabled || endpoints.length === 0) return;
792
+ const url = this.config.ingestUrl.replace(/\/v1\/events$/, "/v1/declare-endpoints");
793
+ try {
794
+ await fetch(url, {
795
+ method: "POST",
796
+ headers: {
797
+ Authorization: `Bearer ${this.config.apiKey}`,
798
+ "Content-Type": "application/json",
799
+ "User-Agent": `@anomira/node-sdk/0.1.0`
800
+ },
801
+ body: JSON.stringify({ appId: this.config.appId, endpoints }),
802
+ signal: AbortSignal.timeout(1e4)
803
+ });
804
+ } catch {
805
+ }
806
+ }
774
807
  /**
775
808
  * Flush all pending events immediately.
776
809
  * Useful before a graceful shutdown outside of the process lifecycle hooks.
@@ -1111,10 +1144,11 @@ function createFastifyPlugin2(client) {
1111
1144
  };
1112
1145
  }
1113
1146
 
1147
+ exports.Anomira = AnomiraClient;
1114
1148
  exports.EventName = EventName;
1115
- exports.SentinelAPI = SentinelClient;
1149
+ exports.SentinelAPI = AnomiraClient;
1116
1150
  exports.createExpressMiddleware = createExpressMiddleware2;
1117
1151
  exports.createFastifyPlugin = createFastifyPlugin2;
1118
- exports.default = SentinelClient;
1152
+ exports.default = AnomiraClient;
1119
1153
  //# sourceMappingURL=index.cjs.map
1120
1154
  //# sourceMappingURL=index.cjs.map