@floatingsidewal/bulkhead-core 0.3.0

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/dist/index.mjs ADDED
@@ -0,0 +1,3082 @@
1
+ import {
2
+ CascadeClassifier
3
+ } from "./chunk-4KUXRYNS.mjs";
4
+
5
+ // src/policy/risk.ts
6
+ function assessRisk(results, policy) {
7
+ const allDetections = results.flatMap((r) => r.detections);
8
+ const testDetections = allDetections.filter(
9
+ (d) => d.entityType.startsWith("TEST_DATA_")
10
+ );
11
+ const realDetections = allDetections.filter(
12
+ (d) => !d.entityType.startsWith("TEST_DATA_")
13
+ );
14
+ const testDataFlags = testDetections.map((d) => ({
15
+ value: d.text,
16
+ reason: d.entityType.toLowerCase().replace("test_data_", "") + "-pattern",
17
+ start: d.start,
18
+ end: d.end
19
+ }));
20
+ const score = realDetections.length > 0 ? Math.max(...realDetections.map((d) => d.score)) : 0;
21
+ const level = scoreToLevel(score, policy.riskThresholds);
22
+ const guards = {};
23
+ for (const result of results) {
24
+ if (result.guardName === "testdata") continue;
25
+ const guardDetections = result.detections.filter(
26
+ (d) => !d.entityType.startsWith("TEST_DATA_")
27
+ );
28
+ guards[result.guardName] = {
29
+ level: scoreToLevel(result.score, policy.riskThresholds),
30
+ score: result.score,
31
+ detectionCount: guardDetections.length
32
+ };
33
+ }
34
+ const issues = classifyIssues(realDetections, testDetections, policy);
35
+ return { level, score, guards, issues, testDataFlags };
36
+ }
37
+ function scoreToLevel(score, thresholds) {
38
+ if (score >= thresholds.critical) return "critical";
39
+ if (score >= thresholds.high) return "high";
40
+ if (score >= thresholds.medium) return "medium";
41
+ if (score >= thresholds.low) return "low";
42
+ return "none";
43
+ }
44
+ function classifyIssues(realDetections, testDetections, policy) {
45
+ const groups = /* @__PURE__ */ new Map();
46
+ for (const d of realDetections) {
47
+ const key = `${d.guardName}:${d.entityType}`;
48
+ const group = groups.get(key);
49
+ if (group) {
50
+ group.detections.push(d);
51
+ } else {
52
+ groups.set(key, {
53
+ detections: [d],
54
+ guardName: d.guardName,
55
+ entityType: d.entityType
56
+ });
57
+ }
58
+ }
59
+ const issues = [];
60
+ for (const [, group] of groups) {
61
+ const maxScore = Math.max(...group.detections.map((d) => d.score));
62
+ const severity = scoreToLevel(maxScore, policy.riskThresholds);
63
+ const isTestData = group.detections.some(
64
+ (d) => testDetections.some(
65
+ (td) => d.start < td.end && d.end > td.start
66
+ )
67
+ );
68
+ const category = guardNameToCategory(group.guardName);
69
+ const sample = group.detections[0]?.text?.slice(0, 50);
70
+ issues.push({
71
+ category,
72
+ entityType: group.entityType,
73
+ severity,
74
+ count: group.detections.length,
75
+ isTestData,
76
+ sample
77
+ });
78
+ }
79
+ return issues.sort((a, b) => {
80
+ const levelOrder = {
81
+ critical: 0,
82
+ high: 1,
83
+ medium: 2,
84
+ low: 3,
85
+ none: 4
86
+ };
87
+ const levelDiff = levelOrder[a.severity] - levelOrder[b.severity];
88
+ if (levelDiff !== 0) return levelDiff;
89
+ return b.count - a.count;
90
+ });
91
+ }
92
+ function guardNameToCategory(guardName) {
93
+ switch (guardName) {
94
+ case "pii":
95
+ return "pii";
96
+ case "secret":
97
+ return "secret";
98
+ case "injection":
99
+ return "injection";
100
+ case "leakage":
101
+ return "leakage";
102
+ default:
103
+ return "pii";
104
+ }
105
+ }
106
+
107
+ // src/engine/engine.ts
108
+ var GuardrailsEngine = class {
109
+ guards = [];
110
+ config;
111
+ cascade = null;
112
+ constructor(config) {
113
+ this.config = {
114
+ guards: {},
115
+ ...config
116
+ };
117
+ }
118
+ /** Register a guard with the engine */
119
+ addGuard(guard) {
120
+ this.guards.push(guard);
121
+ return this;
122
+ }
123
+ /** Register multiple guards */
124
+ addGuards(guards) {
125
+ for (const guard of guards) {
126
+ this.addGuard(guard);
127
+ }
128
+ return this;
129
+ }
130
+ /** Get configuration for a specific guard */
131
+ getGuardConfig(guardName) {
132
+ return this.config.guards[guardName];
133
+ }
134
+ /** Run all enabled guards against the input text */
135
+ async analyze(text) {
136
+ const results = [];
137
+ for (const guard of this.guards) {
138
+ const guardConfig = this.getGuardConfig(guard.name);
139
+ if (guardConfig?.enabled === false) {
140
+ continue;
141
+ }
142
+ const result = await guard.analyze(text, guardConfig);
143
+ results.push(result);
144
+ }
145
+ return results;
146
+ }
147
+ /** Run all guards and return a single pass/fail with all detections */
148
+ async scan(text) {
149
+ const results = await this.analyze(text);
150
+ const passed = results.every((r) => r.passed);
151
+ let redactedText;
152
+ for (const result of results) {
153
+ if (result.redactedText) {
154
+ redactedText = result.redactedText;
155
+ }
156
+ }
157
+ return { passed, results, redactedText };
158
+ }
159
+ /** Get list of registered guard names */
160
+ get guardNames() {
161
+ return this.guards.map((g) => g.name);
162
+ }
163
+ /** Whether the cascade is ready (BERT model loaded if enabled) */
164
+ get cascadeReady() {
165
+ if (!this.cascade) return true;
166
+ return this.cascade.ready;
167
+ }
168
+ /** Initialize or update the cascade classifier */
169
+ initCascade(config) {
170
+ this.cascade = new CascadeClassifier(config);
171
+ for (const guard of this.guards) {
172
+ this.cascade.addRegexGuard(guard);
173
+ }
174
+ return this.cascade;
175
+ }
176
+ /** Run the full cascade (regex + BERT + optional LLM) */
177
+ async deepScan(text) {
178
+ if (!this.cascade) {
179
+ return this.analyze(text);
180
+ }
181
+ const cascadeResult = await this.cascade.deepScan(text);
182
+ return [cascadeResult];
183
+ }
184
+ /** Run regex + BERT only (no LLM) */
185
+ async modelScan(text) {
186
+ if (!this.cascade) {
187
+ return this.analyze(text);
188
+ }
189
+ const cascadeResult = await this.cascade.modelScan(text);
190
+ return [cascadeResult];
191
+ }
192
+ /** Update engine configuration */
193
+ updateConfig(config) {
194
+ this.config = { ...this.config, ...config };
195
+ if (config.guards) {
196
+ this.config.guards = { ...this.config.guards, ...config.guards };
197
+ }
198
+ }
199
+ /** Run all guards and return risk assessment alongside results */
200
+ async policyScan(text, policy) {
201
+ const { passed, results, redactedText } = await this.scan(text);
202
+ const risk = assessRisk(results, policy);
203
+ return { passed, risk, results, redactedText };
204
+ }
205
+ /** Clean up resources (terminate BERT worker, etc.) */
206
+ async dispose() {
207
+ if (this.cascade) {
208
+ await this.cascade.dispose();
209
+ this.cascade = null;
210
+ }
211
+ }
212
+ };
213
+
214
+ // src/guards/base.guard.ts
215
+ var CONTEXT_RADIUS = 150;
216
+ var DEFAULT_CONFIG = {
217
+ enabled: true,
218
+ threshold: 0.5,
219
+ mode: "redact"
220
+ };
221
+ var BaseGuard = class {
222
+ mergeConfig(config) {
223
+ return { ...DEFAULT_CONFIG, ...config };
224
+ }
225
+ /** Build a GuardResult from detections */
226
+ buildResult(text, detections, mode) {
227
+ const passed = detections.length === 0;
228
+ const score = detections.length > 0 ? Math.max(...detections.map((d) => d.score)) : 0;
229
+ let reason;
230
+ if (passed) {
231
+ reason = "No issues detected";
232
+ } else {
233
+ const types = [...new Set(detections.map((d) => d.entityType))];
234
+ reason = `Detected: ${types.join(", ")}`;
235
+ }
236
+ const result = {
237
+ passed,
238
+ reason,
239
+ guardName: this.name,
240
+ score,
241
+ detections
242
+ };
243
+ if (mode === "redact" && !passed) {
244
+ result.redactedText = this.applyRedactions(text, detections);
245
+ }
246
+ return result;
247
+ }
248
+ /** Extract surrounding context for a detection */
249
+ extractContext(text, start, end) {
250
+ const ctxStart = Math.max(0, start - CONTEXT_RADIUS);
251
+ const ctxEnd = Math.min(text.length, end + CONTEXT_RADIUS);
252
+ return text.slice(ctxStart, ctxEnd);
253
+ }
254
+ /** Create a detection with provenance fields pre-filled for regex source */
255
+ makeDetection(text, partial, source = "regex", disposition = "confirmed") {
256
+ return {
257
+ ...partial,
258
+ source,
259
+ context: this.extractContext(text, partial.start, partial.end),
260
+ disposition
261
+ };
262
+ }
263
+ /** Replace detected text with [REDACTED-TYPE] markers */
264
+ applyRedactions(text, detections) {
265
+ const sorted = [...detections].sort((a, b) => b.start - a.start);
266
+ let result = text;
267
+ for (const detection of sorted) {
268
+ const replacement = `[REDACTED-${detection.entityType}]`;
269
+ result = result.slice(0, detection.start) + replacement + result.slice(detection.end);
270
+ }
271
+ return result;
272
+ }
273
+ };
274
+
275
+ // src/validators/checksums.ts
276
+ function luhn(value) {
277
+ const digits = value.replace(/\D/g, "");
278
+ if (digits.length === 0) return false;
279
+ let sum = 0;
280
+ let alternate = false;
281
+ for (let i = digits.length - 1; i >= 0; i--) {
282
+ let n = parseInt(digits[i], 10);
283
+ if (alternate) {
284
+ n *= 2;
285
+ if (n > 9) n -= 9;
286
+ }
287
+ sum += n;
288
+ alternate = !alternate;
289
+ }
290
+ return sum % 10 === 0;
291
+ }
292
+ function ibanMod97(iban) {
293
+ const cleaned = iban.replace(/[\s-]/g, "").toUpperCase();
294
+ if (cleaned.length < 4) return false;
295
+ const rearranged = cleaned.slice(4) + cleaned.slice(0, 4);
296
+ let numeric = "";
297
+ for (const char of rearranged) {
298
+ const code = char.charCodeAt(0);
299
+ if (code >= 65 && code <= 90) {
300
+ numeric += (code - 55).toString();
301
+ } else {
302
+ numeric += char;
303
+ }
304
+ }
305
+ let remainder = 0;
306
+ for (const char of numeric) {
307
+ remainder = (remainder * 10 + parseInt(char, 10)) % 97;
308
+ }
309
+ return remainder === 1;
310
+ }
311
+ function abaRouting(value) {
312
+ const digits = value.replace(/\D/g, "");
313
+ if (digits.length !== 9) return false;
314
+ const weights = [3, 7, 1, 3, 7, 1, 3, 7, 1];
315
+ let sum = 0;
316
+ for (let i = 0; i < 9; i++) {
317
+ sum += parseInt(digits[i], 10) * weights[i];
318
+ }
319
+ return sum % 10 === 0;
320
+ }
321
+ function npiLuhn(value) {
322
+ const digits = value.replace(/\D/g, "");
323
+ if (digits.length !== 10) return false;
324
+ const prefixed = "80840" + digits;
325
+ const nums = prefixed.split("").map(Number);
326
+ let checksum = 0;
327
+ for (let i = nums.length - 1; i >= 0; i--) {
328
+ const pos = nums.length - 1 - i;
329
+ let n = nums[i];
330
+ if (pos % 2 === 1) {
331
+ n *= 2;
332
+ if (n > 9) n -= 9;
333
+ }
334
+ checksum += n;
335
+ }
336
+ return checksum % 10 === 0;
337
+ }
338
+ function deaChecksum(value) {
339
+ const cleaned = value.replace(/[\s-]/g, "");
340
+ if (cleaned.length < 3) return false;
341
+ const numericPart = cleaned.slice(2);
342
+ const digits = numericPart.split("").map(Number);
343
+ if (digits.some(isNaN)) return false;
344
+ const check = digits.pop();
345
+ const even = digits.filter((_, i) => i % 2 === 0);
346
+ const odd = digits.filter((_, i) => i % 2 === 1);
347
+ const sum = 2 * even.reduce((a, b) => a + b, 0) + odd.reduce((a, b) => a + b, 0);
348
+ return (sum - check) % 10 === 0;
349
+ }
350
+ function shannonEntropy(value) {
351
+ if (value.length === 0) return 0;
352
+ const freq = /* @__PURE__ */ new Map();
353
+ for (const char of value) {
354
+ freq.set(char, (freq.get(char) || 0) + 1);
355
+ }
356
+ let entropy = 0;
357
+ for (const count of freq.values()) {
358
+ const p = count / value.length;
359
+ if (p > 0) {
360
+ entropy -= p * Math.log2(p);
361
+ }
362
+ }
363
+ return entropy;
364
+ }
365
+ function validateSsn(value) {
366
+ const digits = value.replace(/\D/g, "");
367
+ if (digits.length !== 9) return false;
368
+ if (digits.split("").every((c) => c === digits[0])) return false;
369
+ if (digits.slice(3, 5) === "00") return false;
370
+ if (digits.slice(5) === "0000") return false;
371
+ const invalidPrefixes = ["000", "666", "123456789", "98765432", "078051120"];
372
+ for (const prefix of invalidPrefixes) {
373
+ if (digits.startsWith(prefix)) return false;
374
+ }
375
+ if (digits[0] === "9") return false;
376
+ return true;
377
+ }
378
+ function validateMac(value) {
379
+ const cleaned = value.replace(/[:\-.]/g, "").toUpperCase();
380
+ if (!/^[0-9A-F]{12}$/.test(cleaned)) return false;
381
+ if (cleaned === "FFFFFFFFFFFF") return false;
382
+ if (cleaned === "000000000000") return false;
383
+ return true;
384
+ }
385
+
386
+ // src/patterns/pii/generic.ts
387
+ var CREDIT_CARD = {
388
+ entityType: "CREDIT_CARD",
389
+ patterns: [
390
+ /\b(?!1\d{12}(?!\d))((4\d{3})|(5[0-5]\d{2})|(6\d{3})|(1\d{3})|(3\d{3}))[- ]?(\d{3,4})[- ]?(\d{3,4})[- ]?(\d{3,5})\b/g
391
+ ],
392
+ validate: (match) => luhn(match.replace(/[\s-]/g, "")),
393
+ contextWords: [
394
+ "credit",
395
+ "card",
396
+ "visa",
397
+ "mastercard",
398
+ "cc",
399
+ "amex",
400
+ "discover",
401
+ "jcb",
402
+ "diners",
403
+ "maestro",
404
+ "instapayment"
405
+ ],
406
+ baseConfidence: "medium",
407
+ baseScore: 0.3
408
+ };
409
+ var EMAIL_ADDRESS = {
410
+ entityType: "EMAIL_ADDRESS",
411
+ patterns: [
412
+ /\b(?:[a-zA-Z0-9!#$%&'*+\-/=?^_`{|}~](?:[a-zA-Z0-9!#$%&'*+\-/=?^_`{|}~.]{0,62}[a-zA-Z0-9!#$%&'*+\-/=?^_`{|}~])?)@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}\b/g
413
+ ],
414
+ contextWords: ["email", "e-mail", "mail"],
415
+ baseConfidence: "medium",
416
+ baseScore: 0.5
417
+ };
418
+ var IBAN_CODE = {
419
+ entityType: "IBAN_CODE",
420
+ patterns: [
421
+ /(?<![A-Z0-9])([A-Z]{2}[0-9]{2}(?:[ -]?[A-Z0-9]{4}){2,7}(?:[ -]?[A-Z0-9]{1,4})?)(?![A-Z0-9])/g
422
+ ],
423
+ validate: (match) => ibanMod97(match),
424
+ contextWords: ["iban", "bank", "transaction"],
425
+ baseConfidence: "medium",
426
+ baseScore: 0.5
427
+ };
428
+ var IP_ADDRESS = {
429
+ entityType: "IP_ADDRESS",
430
+ patterns: [
431
+ // IPv4
432
+ /\b(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b/g,
433
+ // IPv6 (simplified — common formats)
434
+ /\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b/g,
435
+ /\b(?:[0-9a-fA-F]{1,4}:){1,7}:\b/g,
436
+ /\b(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}\b/g
437
+ ],
438
+ contextWords: ["ip", "ipv4", "ipv6", "address"],
439
+ baseConfidence: "medium",
440
+ baseScore: 0.6
441
+ };
442
+ var MAC_ADDRESS = {
443
+ entityType: "MAC_ADDRESS",
444
+ patterns: [
445
+ // Colon or hyphen separated
446
+ /\b[0-9A-Fa-f]{2}([:-])(?:[0-9A-Fa-f]{2}\1){4}[0-9A-Fa-f]{2}\b/g,
447
+ // Cisco dot format
448
+ /\b[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\b/g
449
+ ],
450
+ validate: validateMac,
451
+ contextWords: [
452
+ "mac",
453
+ "mac address",
454
+ "hardware address",
455
+ "physical address",
456
+ "ethernet"
457
+ ],
458
+ baseConfidence: "medium",
459
+ baseScore: 0.6
460
+ };
461
+ var PHONE_NUMBER = {
462
+ entityType: "PHONE_NUMBER",
463
+ patterns: [
464
+ // International format
465
+ /\b\+?1?[\s.-]?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}\b/g,
466
+ // International with country code
467
+ /\b\+\d{1,3}[\s.-]?\(?\d{1,4}\)?[\s.-]?\d{2,4}[\s.-]?\d{2,4}[\s.-]?\d{0,4}\b/g
468
+ ],
469
+ contextWords: [
470
+ "phone",
471
+ "number",
472
+ "telephone",
473
+ "cell",
474
+ "cellphone",
475
+ "mobile",
476
+ "call",
477
+ "tel",
478
+ "fax"
479
+ ],
480
+ baseConfidence: "low",
481
+ baseScore: 0.4
482
+ };
483
+ var URL = {
484
+ entityType: "URL",
485
+ patterns: [
486
+ /\bhttps?:\/\/[^\s<>"']+/gi,
487
+ /\bwww\.[^\s<>"']+/gi
488
+ ],
489
+ contextWords: ["url", "website", "link", "href"],
490
+ baseConfidence: "medium",
491
+ baseScore: 0.6
492
+ };
493
+ var CRYPTO = {
494
+ entityType: "CRYPTO",
495
+ patterns: [
496
+ // Bitcoin addresses (P2PKH, P2SH, Bech32)
497
+ /(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,59}/g
498
+ ],
499
+ contextWords: ["wallet", "btc", "bitcoin", "crypto", "blockchain"],
500
+ baseConfidence: "medium",
501
+ baseScore: 0.5
502
+ };
503
+ var DATE_TIME = {
504
+ entityType: "DATE_TIME",
505
+ patterns: [
506
+ // ISO 8601
507
+ /\b\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:[+-][0-2]\d:[0-5]\d|Z)\b/g,
508
+ // mm/dd/yyyy or dd/mm/yyyy
509
+ /\b(?:[0-3]?\d[/.-][0-3]?\d[/.-](?:\d{4}|\d{2}))\b/g,
510
+ // yyyy-mm-dd
511
+ /\b\d{4}[/.-](?:0?[1-9]|1[0-2])[/.-](?:0?[1-9]|[12]\d|3[01])\b/g
512
+ ],
513
+ contextWords: ["date", "birthday", "born", "dob"],
514
+ baseConfidence: "low",
515
+ baseScore: 0.3
516
+ };
517
+ var GENERIC_PATTERNS = [
518
+ CREDIT_CARD,
519
+ EMAIL_ADDRESS,
520
+ IBAN_CODE,
521
+ IP_ADDRESS,
522
+ MAC_ADDRESS,
523
+ PHONE_NUMBER,
524
+ URL,
525
+ CRYPTO,
526
+ DATE_TIME
527
+ ];
528
+
529
+ // src/patterns/pii/us.ts
530
+ var US_SSN = {
531
+ entityType: "US_SSN",
532
+ patterns: [
533
+ // SSN with delimiters (medium confidence)
534
+ /\b(\d{3})[- .](\d{2})[- .](\d{4})\b/g,
535
+ // SSN without delimiters (very weak — needs context)
536
+ /\b\d{9}\b/g
537
+ ],
538
+ validate: validateSsn,
539
+ contextWords: ["social", "security", "ssn", "ssns", "ssid"],
540
+ baseConfidence: "medium",
541
+ baseScore: 0.5
542
+ };
543
+ var US_DRIVER_LICENSE = {
544
+ entityType: "US_DRIVER_LICENSE",
545
+ patterns: [
546
+ // State-specific alphanumeric formats
547
+ /\b(?:[A-Z]\d{3,6}|[A-Z]\d{5,9}|[A-Z]\d{6,8}|[A-Z]\d{4,8}|[A-Z]\d{9,11}|[A-Z]{1,2}\d{5,6}|H\d{8}|V\d{6}|X\d{8}|[A-Z]{2}\d{2,5}|[A-Z]{2}\d{3,7}|\d{2}[A-Z]{3}\d{5,6}|[A-Z]\d{13,14}|[A-Z]\d{18}|[A-Z]\d{6}R|[A-Z]\d{9}|[A-Z]\d{1,12}|\d{9}[A-Z]|[A-Z]{2}\d{6}[A-Z]|\d{8}[A-Z]{2}|\d{3}[A-Z]{2}\d{4}|[A-Z]\d[A-Z]\d[A-Z]|\d{7,8}[A-Z])\b/g
548
+ ],
549
+ contextWords: [
550
+ "driver",
551
+ "license",
552
+ "permit",
553
+ "lic",
554
+ "identification",
555
+ "dls",
556
+ "cdls",
557
+ "driving"
558
+ ],
559
+ baseConfidence: "low",
560
+ baseScore: 0.3
561
+ };
562
+ var US_PASSPORT = {
563
+ entityType: "US_PASSPORT",
564
+ patterns: [
565
+ // Next generation passport (letter + 8 digits)
566
+ /\b[A-Z]\d{8}\b/g,
567
+ // Standard passport (9 digits)
568
+ /\b\d{9}\b/g
569
+ ],
570
+ contextWords: [
571
+ "us",
572
+ "united",
573
+ "states",
574
+ "passport",
575
+ "travel",
576
+ "document"
577
+ ],
578
+ baseConfidence: "low",
579
+ baseScore: 0.1
580
+ };
581
+ var US_BANK_NUMBER = {
582
+ entityType: "US_BANK_NUMBER",
583
+ patterns: [/\b\d{8,17}\b/g],
584
+ contextWords: [
585
+ "check",
586
+ "account",
587
+ "acct",
588
+ "bank",
589
+ "save",
590
+ "debit",
591
+ "routing"
592
+ ],
593
+ baseConfidence: "low",
594
+ baseScore: 0.05
595
+ };
596
+ var US_ITIN = {
597
+ entityType: "US_ITIN",
598
+ patterns: [
599
+ // With delimiters (medium)
600
+ /\b9\d{2}[- ](5\d|6[0-5]|7\d|8[0-8]|9[0-24-9])[- ]\d{4}\b/g,
601
+ // Without delimiters (weak)
602
+ /\b9\d{2}(5\d|6[0-5]|7\d|8[0-8]|9[0-24-9])\d{4}\b/g
603
+ ],
604
+ contextWords: [
605
+ "individual",
606
+ "taxpayer",
607
+ "itin",
608
+ "tax",
609
+ "payer",
610
+ "taxid",
611
+ "tin"
612
+ ],
613
+ baseConfidence: "medium",
614
+ baseScore: 0.5
615
+ };
616
+ var US_MBI = {
617
+ entityType: "US_MBI",
618
+ patterns: (() => {
619
+ const A = "[ACDEFGHJKMNPQRTUVWXY]";
620
+ const AN = "[0-9ACDEFGHJKMNPQRTUVWXY]";
621
+ const N = "[0-9]";
622
+ const base = `${N}${A}${AN}${N}${A}${AN}${N}${A}${A}${N}${N}`;
623
+ const withDash = `${N}${A}${AN}${N}-${A}${AN}${N}-${A}${A}${N}${N}`;
624
+ return [new RegExp(`\\b${base}\\b`, "g"), new RegExp(`\\b${withDash}\\b`, "g")];
625
+ })(),
626
+ contextWords: [
627
+ "medicare",
628
+ "mbi",
629
+ "beneficiary",
630
+ "cms",
631
+ "medicaid",
632
+ "hic",
633
+ "hicn"
634
+ ],
635
+ baseConfidence: "medium",
636
+ baseScore: 0.5
637
+ };
638
+ var US_NPI = {
639
+ entityType: "US_NPI",
640
+ patterns: [
641
+ // With delimiters
642
+ /\b[12]\d{3}[ -]\d{3}[ -]\d{3}\b/g,
643
+ // Without delimiters
644
+ /\b[12]\d{9}\b/g
645
+ ],
646
+ validate: (match) => {
647
+ const digits = match.replace(/\D/g, "");
648
+ if (digits.length > 1 && new Set(digits.slice(0, -1)).size === 1) return false;
649
+ return npiLuhn(match);
650
+ },
651
+ contextWords: [
652
+ "npi",
653
+ "national provider",
654
+ "provider",
655
+ "provider id",
656
+ "provider identifier",
657
+ "taxonomy"
658
+ ],
659
+ baseConfidence: "low",
660
+ baseScore: 0.1
661
+ };
662
+ var ABA_ROUTING_NUMBER = {
663
+ entityType: "ABA_ROUTING_NUMBER",
664
+ patterns: [
665
+ // With dashes
666
+ /\b[0123678]\d{3}-\d{4}-\d\b/g,
667
+ // Without dashes
668
+ /\b[0123678]\d{8}\b/g
669
+ ],
670
+ validate: abaRouting,
671
+ contextWords: [
672
+ "aba",
673
+ "routing",
674
+ "abarouting",
675
+ "association",
676
+ "bankrouting"
677
+ ],
678
+ baseConfidence: "low",
679
+ baseScore: 0.05
680
+ };
681
+ var MEDICAL_LICENSE = {
682
+ entityType: "MEDICAL_LICENSE",
683
+ patterns: [
684
+ /[abcdefghjklmprstuxABCDEFGHJKLMPRSTUX][a-zA-Z]\d{7}/g,
685
+ /[abcdefghjklmprstuxABCDEFGHJKLMPRSTUX]9\d{7}/g
686
+ ],
687
+ validate: deaChecksum,
688
+ contextWords: ["medical", "certificate", "DEA", "dea"],
689
+ baseConfidence: "low",
690
+ baseScore: 0.4
691
+ };
692
+ var US_PATTERNS = [
693
+ US_SSN,
694
+ US_DRIVER_LICENSE,
695
+ US_PASSPORT,
696
+ US_BANK_NUMBER,
697
+ US_ITIN,
698
+ US_MBI,
699
+ US_NPI,
700
+ ABA_ROUTING_NUMBER,
701
+ MEDICAL_LICENSE
702
+ ];
703
+
704
+ // src/patterns/pii/uk.ts
705
+ var UK_NHS = {
706
+ entityType: "UK_NHS",
707
+ patterns: [/\b(\d{3})[- ]?(\d{3})[- ]?(\d{4})\b/g],
708
+ validate: (match) => {
709
+ const digits = match.replace(/\D/g, "");
710
+ if (digits.length !== 10) return false;
711
+ let total = 0;
712
+ for (let i = 0; i < 10; i++) {
713
+ total += parseInt(digits[i], 10) * (10 - i);
714
+ }
715
+ return total % 11 === 0;
716
+ },
717
+ contextWords: [
718
+ "national health service",
719
+ "nhs",
720
+ "health services authority",
721
+ "health authority"
722
+ ],
723
+ baseConfidence: "medium",
724
+ baseScore: 0.5
725
+ };
726
+ var UK_NINO = {
727
+ entityType: "UK_NINO",
728
+ patterns: [
729
+ /\b(?!BG|GB|NK|KN|NT|TN|ZZ)(?:[A-CEGHJ-PR-TW-Z][A-CEGHJ-NPR-TW-Z])\s?\d{2}\s?\d{2}\s?\d{2}\s?[A-D]\b/gi
730
+ ],
731
+ contextWords: ["national insurance", "ni number", "nino"],
732
+ baseConfidence: "medium",
733
+ baseScore: 0.5
734
+ };
735
+ var UK_PASSPORT = {
736
+ entityType: "UK_PASSPORT",
737
+ patterns: [/\b[A-Z]{2}\d{7}\b/g],
738
+ contextWords: [
739
+ "passport",
740
+ "passport number",
741
+ "travel document",
742
+ "uk passport",
743
+ "british passport",
744
+ "her majesty",
745
+ "his majesty",
746
+ "hm passport",
747
+ "hmpo"
748
+ ],
749
+ baseConfidence: "low",
750
+ baseScore: 0.1
751
+ };
752
+ var UK_POSTCODE = {
753
+ entityType: "UK_POSTCODE",
754
+ patterns: [
755
+ /\b(?:GIR\s?0AA|[A-PR-UWYZ]\d[A-HJKPSTUW]?\s?\d[ABD-HJLNP-UW-Z]{2}|[A-PR-UWYZ]\d{2}\s?\d[ABD-HJLNP-UW-Z]{2}|[A-PR-UWYZ][A-HK-Y]\d[ABEHMNPRVWXY]?\s?\d[ABD-HJLNP-UW-Z]{2}|[A-PR-UWYZ][A-HK-Y]\d{2}\s?\d[ABD-HJLNP-UW-Z]{2})\b/g
756
+ ],
757
+ contextWords: [
758
+ "postcode",
759
+ "post code",
760
+ "postal code",
761
+ "zip",
762
+ "address",
763
+ "delivery",
764
+ "mailing",
765
+ "shipping"
766
+ ],
767
+ baseConfidence: "low",
768
+ baseScore: 0.1
769
+ };
770
+ var UK_VEHICLE_REGISTRATION = {
771
+ entityType: "UK_VEHICLE_REGISTRATION",
772
+ patterns: [
773
+ // Current format
774
+ /\b[A-HJ-PR-Y]{2}(?:0[1-9]|[1-7]\d)[- ]?[A-HJ-PR-Z]{3}\b/g,
775
+ // Prefix format
776
+ /\b[A-HJ-NPR-TV-Y]\d{1,3}[- ]?[A-HJ-PR-Y][A-HJ-PR-Z]{2}\b/g,
777
+ // Suffix format
778
+ /\b[A-HJ-PR-Z]{3}[- ]?\d{1,3}[- ]?[A-HJ-NPR-TV-Y]\b/g
779
+ ],
780
+ contextWords: [
781
+ "vehicle",
782
+ "registration",
783
+ "number plate",
784
+ "licence plate",
785
+ "license plate",
786
+ "reg",
787
+ "vrn",
788
+ "dvla",
789
+ "v5c",
790
+ "mot",
791
+ "car"
792
+ ],
793
+ baseConfidence: "low",
794
+ baseScore: 0.2
795
+ };
796
+ var UK_PATTERNS = [
797
+ UK_NHS,
798
+ UK_NINO,
799
+ UK_PASSPORT,
800
+ UK_POSTCODE,
801
+ UK_VEHICLE_REGISTRATION
802
+ ];
803
+
804
+ // src/patterns/pii/eu.ts
805
+ var ES_NIF = {
806
+ entityType: "ES_NIF",
807
+ patterns: [/\b\d{7,8}[-]?[A-Z]\b/g],
808
+ validate: (match) => {
809
+ const cleaned = match.replace(/-/g, "");
810
+ const letter = cleaned.slice(-1);
811
+ const number = parseInt(cleaned.replace(/[^0-9]/g, ""), 10);
812
+ const letters = "TRWAGMYFPDXBNJZSQVHLCKE";
813
+ return letter === letters[number % 23];
814
+ },
815
+ contextWords: ["documento nacional de identidad", "dni", "nif", "identificaci\xF3n"],
816
+ baseConfidence: "medium",
817
+ baseScore: 0.5
818
+ };
819
+ var ES_NIE = {
820
+ entityType: "ES_NIE",
821
+ patterns: [/\b[XYZ]\d{7}[-]?[A-Z]\b/g],
822
+ validate: (match) => {
823
+ const cleaned = match.replace(/-/g, "");
824
+ if (cleaned.length < 8 || cleaned.length > 9) return false;
825
+ const letter = cleaned.slice(-1);
826
+ const prefix = "XYZ".indexOf(cleaned[0]);
827
+ if (prefix === -1) return false;
828
+ const number = parseInt(prefix.toString() + cleaned.slice(1, -1), 10);
829
+ const letters = "TRWAGMYFPDXBNJZSQVHLCKE";
830
+ return letter === letters[number % 23];
831
+ },
832
+ contextWords: ["n\xFAmero de identificaci\xF3n de extranjero", "nie"],
833
+ baseConfidence: "medium",
834
+ baseScore: 0.5
835
+ };
836
+ var IT_FISCAL_CODE = {
837
+ entityType: "IT_FISCAL_CODE",
838
+ patterns: [
839
+ /(?:[A-Z][AEIOU][AEIOUX]|[AEIOU]X{2}|[B-DF-HJ-NP-TV-Z]{2}[A-Z]){2}(?:[\dLMNP-V]{2}(?:[A-EHLMPR-T](?:[04LQ][1-9MNP-V]|[15MR][\dLMNP-V]|[26NS][0-8LMNP-U])|[DHPS][37PT][0L]|[ACELMRT][37PT][01LM]|[AC-EHLMPR-T][26NS][9V])|(?:[02468LNQSU][048LQU]|[13579MPRTV][26NS])B[26NS][9V])(?:[A-MZ][1-9MNP-V][\dLMNP-V]{2}|[A-M][0L](?:[1-9MNP-V][\dLMNP-V]|[0L][1-9MNP-V]))[A-Z]/gi
840
+ ],
841
+ validate: (match) => {
842
+ const text = match.toUpperCase();
843
+ if (text.length !== 16) return false;
844
+ const control = text[15];
845
+ const toValidate = text.slice(0, 15);
846
+ const mapOdd = {
847
+ "0": 1,
848
+ "1": 0,
849
+ "2": 5,
850
+ "3": 7,
851
+ "4": 9,
852
+ "5": 13,
853
+ "6": 15,
854
+ "7": 17,
855
+ "8": 19,
856
+ "9": 21,
857
+ A: 1,
858
+ B: 0,
859
+ C: 5,
860
+ D: 7,
861
+ E: 9,
862
+ F: 13,
863
+ G: 15,
864
+ H: 17,
865
+ I: 19,
866
+ J: 21,
867
+ K: 2,
868
+ L: 4,
869
+ M: 18,
870
+ N: 20,
871
+ O: 11,
872
+ P: 3,
873
+ Q: 6,
874
+ R: 8,
875
+ S: 12,
876
+ T: 14,
877
+ U: 16,
878
+ V: 10,
879
+ W: 22,
880
+ X: 25,
881
+ Y: 24,
882
+ Z: 23
883
+ };
884
+ const mapEven = {
885
+ "0": 0,
886
+ "1": 1,
887
+ "2": 2,
888
+ "3": 3,
889
+ "4": 4,
890
+ "5": 5,
891
+ "6": 6,
892
+ "7": 7,
893
+ "8": 8,
894
+ "9": 9,
895
+ A: 0,
896
+ B: 1,
897
+ C: 2,
898
+ D: 3,
899
+ E: 4,
900
+ F: 5,
901
+ G: 6,
902
+ H: 7,
903
+ I: 8,
904
+ J: 9,
905
+ K: 10,
906
+ L: 11,
907
+ M: 12,
908
+ N: 13,
909
+ O: 14,
910
+ P: 15,
911
+ Q: 16,
912
+ R: 17,
913
+ S: 18,
914
+ T: 19,
915
+ U: 20,
916
+ V: 21,
917
+ W: 22,
918
+ X: 23,
919
+ Y: 24,
920
+ Z: 25
921
+ };
922
+ let oddSum = 0;
923
+ let evenSum = 0;
924
+ for (let i = 0; i < toValidate.length; i++) {
925
+ if (i % 2 === 0) {
926
+ oddSum += mapOdd[toValidate[i]] ?? 0;
927
+ } else {
928
+ evenSum += mapEven[toValidate[i]] ?? 0;
929
+ }
930
+ }
931
+ const expected = String.fromCharCode(65 + (oddSum + evenSum) % 26);
932
+ return expected === control;
933
+ },
934
+ contextWords: ["codice fiscale", "cf"],
935
+ baseConfidence: "medium",
936
+ baseScore: 0.3
937
+ };
938
+ var IT_DRIVER_LICENSE = {
939
+ entityType: "IT_DRIVER_LICENSE",
940
+ patterns: [
941
+ /\b(?:[A-Z]{2}\d{7}[A-Z]|U1[BCDEFGHLJKMNPRSTUWYXZ0-9]{7}[A-Z])\b/gi
942
+ ],
943
+ contextWords: ["patente", "patente di guida", "licenza", "licenza di guida"],
944
+ baseConfidence: "low",
945
+ baseScore: 0.2
946
+ };
947
+ var IT_VAT_CODE = {
948
+ entityType: "IT_VAT_CODE",
949
+ patterns: [/\b\d{11}\b/g],
950
+ validate: (match) => {
951
+ const digits = match.replace(/[\s_]/g, "");
952
+ if (digits.length !== 11) return false;
953
+ if (digits === "00000000000") return false;
954
+ let x = 0;
955
+ let y = 0;
956
+ for (let i = 0; i < 5; i++) {
957
+ x += parseInt(digits[2 * i], 10);
958
+ let tmpY = parseInt(digits[2 * i + 1], 10) * 2;
959
+ if (tmpY > 9) tmpY -= 9;
960
+ y += tmpY;
961
+ }
962
+ const t = (x + y) % 10;
963
+ const c = (10 - t) % 10;
964
+ return c === parseInt(digits[10], 10);
965
+ },
966
+ contextWords: ["piva", "partita iva", "pi"],
967
+ baseConfidence: "low",
968
+ baseScore: 0.1
969
+ };
970
+ var IT_PASSPORT = {
971
+ entityType: "IT_PASSPORT",
972
+ patterns: [/\b[A-Z]{2}\d{7}\b/gi],
973
+ contextWords: ["passaporto", "elettronico", "italiano", "viaggio", "documento"],
974
+ baseConfidence: "low",
975
+ baseScore: 0.01
976
+ };
977
+ var IT_IDENTITY_CARD = {
978
+ entityType: "IT_IDENTITY_CARD",
979
+ patterns: [
980
+ /\b[A-Z]{2}\s?\d{7}\b/gi,
981
+ /\b\d{7}[A-Z]{2}\b/gi,
982
+ /\b[A-Z]{2}\d{5}[A-Z]{2}\b/gi
983
+ ],
984
+ contextWords: ["carta", "identit\xE0", "elettronica", "cie", "documento"],
985
+ baseConfidence: "low",
986
+ baseScore: 0.01
987
+ };
988
+ var PL_PESEL = {
989
+ entityType: "PL_PESEL",
990
+ patterns: [
991
+ /\b\d{2}(?:[02468][1-9]|[13579][012])(?:0[1-9]|[12]\d|3[01])\d{5}\b/g
992
+ ],
993
+ validate: (match) => {
994
+ if (match.length !== 11) return false;
995
+ const digits = match.split("").map(Number);
996
+ const weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
997
+ let checksum = 0;
998
+ for (let i = 0; i < 10; i++) {
999
+ checksum += digits[i] * weights[i];
1000
+ }
1001
+ return checksum % 10 === digits[10];
1002
+ },
1003
+ contextWords: ["pesel"],
1004
+ baseConfidence: "medium",
1005
+ baseScore: 0.4
1006
+ };
1007
+ var FI_PERSONAL_IDENTITY_CODE = {
1008
+ entityType: "FI_PERSONAL_IDENTITY_CODE",
1009
+ patterns: [
1010
+ /\b(\d{6})([+\-ABCDEFYXWVU])(\d{3})([0-9ABCDEFHJKLMNPRSTUVWXY])\b/g
1011
+ ],
1012
+ validate: (match) => {
1013
+ if (match.length !== 11) return false;
1014
+ const datePart = match.slice(0, 6);
1015
+ const individual = match.slice(7, 10);
1016
+ const control = match[10];
1017
+ const validChars = "0123456789ABCDEFHJKLMNPRSTUVWXY";
1018
+ const num = parseInt(datePart + individual, 10);
1019
+ return validChars[num % 31] === control;
1020
+ },
1021
+ contextWords: ["hetu", "henkil\xF6tunnus", "personal identity code"],
1022
+ baseConfidence: "medium",
1023
+ baseScore: 0.5
1024
+ };
1025
+ var SE_PERSONNUMMER = {
1026
+ entityType: "SE_PERSONNUMMER",
1027
+ patterns: [/\b(\d{6,8})([-+]?)\d{4}\b/g],
1028
+ validate: (match) => {
1029
+ const digits = match.replace(/[-+]/g, "");
1030
+ const last10 = digits.slice(-10);
1031
+ if (last10.length !== 10) return false;
1032
+ const month = parseInt(last10.slice(2, 4), 10);
1033
+ let day = parseInt(last10.slice(4, 6), 10);
1034
+ if (day >= 61) day -= 60;
1035
+ if (month < 1 || month > 12 || day < 1 || day > 31) return false;
1036
+ const nums = last10.split("").map(Number);
1037
+ const check = nums[9];
1038
+ let sum = 0;
1039
+ for (let i = 0; i < 9; i++) {
1040
+ let d = nums[i];
1041
+ if (i % 2 === 0) {
1042
+ d *= 2;
1043
+ if (d > 9) d -= 9;
1044
+ }
1045
+ sum += d;
1046
+ }
1047
+ return (sum + check) % 10 === 0;
1048
+ },
1049
+ contextWords: [
1050
+ "personnummer",
1051
+ "svenskt personnummer",
1052
+ "svensk id",
1053
+ "personal identity number",
1054
+ "samordningsnummer"
1055
+ ],
1056
+ baseConfidence: "medium",
1057
+ baseScore: 0.5
1058
+ };
1059
+ var DE_TAX_ID = {
1060
+ entityType: "DE_TAX_ID",
1061
+ patterns: [/\b[1-9]\d{10}\b/g],
1062
+ validate: (match) => {
1063
+ if (match.length !== 11 || !/^\d+$/.test(match)) return false;
1064
+ const digits = match.split("").map(Number);
1065
+ if (new Set(digits.slice(0, 10)).size === 1) return false;
1066
+ let product = 10;
1067
+ for (let i = 0; i < 10; i++) {
1068
+ let total = (digits[i] + product) % 10;
1069
+ if (total === 0) total = 10;
1070
+ product = total * 2 % 11;
1071
+ }
1072
+ let check = 11 - product;
1073
+ if (check === 10) check = 0;
1074
+ return check === digits[10];
1075
+ },
1076
+ contextWords: [
1077
+ "steueridentifikationsnummer",
1078
+ "steuer-id",
1079
+ "steuerid",
1080
+ "idnr",
1081
+ "steuer-idnr",
1082
+ "steuernummer"
1083
+ ],
1084
+ baseConfidence: "medium",
1085
+ baseScore: 0.5
1086
+ };
1087
+ var DE_PASSPORT = {
1088
+ entityType: "DE_PASSPORT",
1089
+ patterns: [
1090
+ /\b[CFGHJKLMNPRTVWXYZ][CFGHJKLMNPRTVWXYZ0-9]{7}[CFGHJKLMNPRTVWXYZ0-9]\b/g,
1091
+ /\bT\d{8}\b/g
1092
+ ],
1093
+ contextWords: [
1094
+ "personalausweis",
1095
+ "ausweis",
1096
+ "reisepass",
1097
+ "pass",
1098
+ "dokumentennummer",
1099
+ "seriennummer"
1100
+ ],
1101
+ baseConfidence: "low",
1102
+ baseScore: 0.4
1103
+ };
1104
+ var EU_PATTERNS = [
1105
+ ES_NIF,
1106
+ ES_NIE,
1107
+ IT_FISCAL_CODE,
1108
+ IT_DRIVER_LICENSE,
1109
+ IT_VAT_CODE,
1110
+ IT_PASSPORT,
1111
+ IT_IDENTITY_CARD,
1112
+ PL_PESEL,
1113
+ FI_PERSONAL_IDENTITY_CODE,
1114
+ SE_PERSONNUMMER,
1115
+ DE_TAX_ID,
1116
+ DE_PASSPORT
1117
+ ];
1118
+
1119
+ // src/validators/verhoeff.ts
1120
+ var D = [
1121
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
1122
+ [1, 2, 3, 4, 0, 6, 7, 8, 9, 5],
1123
+ [2, 3, 4, 0, 1, 7, 8, 9, 5, 6],
1124
+ [3, 4, 0, 1, 2, 8, 9, 5, 6, 7],
1125
+ [4, 0, 1, 2, 3, 9, 5, 6, 7, 8],
1126
+ [5, 9, 8, 7, 6, 0, 4, 3, 2, 1],
1127
+ [6, 5, 9, 8, 7, 1, 0, 4, 3, 2],
1128
+ [7, 6, 5, 9, 8, 2, 1, 0, 4, 3],
1129
+ [8, 7, 6, 5, 9, 3, 2, 1, 0, 4],
1130
+ [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
1131
+ ];
1132
+ var P = [
1133
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
1134
+ [1, 5, 7, 6, 2, 8, 3, 0, 9, 4],
1135
+ [5, 8, 0, 3, 7, 9, 6, 1, 4, 2],
1136
+ [8, 9, 1, 6, 0, 4, 3, 5, 2, 7],
1137
+ [9, 4, 5, 3, 1, 2, 6, 8, 7, 0],
1138
+ [4, 2, 8, 6, 5, 7, 3, 9, 0, 1],
1139
+ [2, 7, 9, 3, 8, 0, 6, 4, 1, 5],
1140
+ [7, 0, 4, 6, 9, 1, 3, 2, 5, 8]
1141
+ ];
1142
+ var INV = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9];
1143
+ function verhoeff(input) {
1144
+ const digits = String(input).split("").map(Number).reverse();
1145
+ let c = 0;
1146
+ for (let i = 0; i < digits.length; i++) {
1147
+ c = D[c][P[i % 8][digits[i]]];
1148
+ }
1149
+ return INV[c] === 0;
1150
+ }
1151
+
1152
+ // src/patterns/pii/apac.ts
1153
+ var SG_NRIC_FIN = {
1154
+ entityType: "SG_NRIC_FIN",
1155
+ patterns: [/\b[STFGM]\d{7}[A-Z]\b/gi],
1156
+ contextWords: ["fin", "nric"],
1157
+ baseConfidence: "medium",
1158
+ baseScore: 0.5
1159
+ };
1160
+ var SG_UEN = {
1161
+ entityType: "SG_UEN",
1162
+ patterns: [
1163
+ /\b\d{8}[A-Z]\b/g,
1164
+ /\b\d{9}[A-Z]\b/g,
1165
+ /\b[TS]\d{2}[A-Z]{2}\d{4}[A-Z]\b/g
1166
+ ],
1167
+ contextWords: ["uen", "unique entity number", "business registration", "acra"],
1168
+ baseConfidence: "low",
1169
+ baseScore: 0.3
1170
+ };
1171
+ var AU_ABN = {
1172
+ entityType: "AU_ABN",
1173
+ patterns: [
1174
+ /\b\d{2}\s\d{3}\s\d{3}\s\d{3}\b/g,
1175
+ /\b\d{11}\b/g
1176
+ ],
1177
+ validate: (match) => {
1178
+ const digits = match.replace(/\s/g, "").split("").map(Number);
1179
+ if (digits.length !== 11) return false;
1180
+ const weights = [10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
1181
+ digits[0] = digits[0] === 0 ? 9 : digits[0] - 1;
1182
+ let sum = 0;
1183
+ for (let i = 0; i < 11; i++) {
1184
+ sum += digits[i] * weights[i];
1185
+ }
1186
+ return sum % 89 === 0;
1187
+ },
1188
+ contextWords: ["australian business number", "abn"],
1189
+ baseConfidence: "low",
1190
+ baseScore: 0.1
1191
+ };
1192
+ var AU_ACN = {
1193
+ entityType: "AU_ACN",
1194
+ patterns: [
1195
+ /\b\d{3}\s\d{3}\s\d{3}\b/g,
1196
+ /\b\d{9}\b/g
1197
+ ],
1198
+ validate: (match) => {
1199
+ const digits = match.replace(/\s/g, "").split("").map(Number);
1200
+ if (digits.length !== 9) return false;
1201
+ const weights = [8, 7, 6, 5, 4, 3, 2, 1];
1202
+ let sum = 0;
1203
+ for (let i = 0; i < 8; i++) {
1204
+ sum += digits[i] * weights[i];
1205
+ }
1206
+ const complement = (10 - sum % 10) % 10;
1207
+ return complement === digits[8];
1208
+ },
1209
+ contextWords: ["australian company number", "acn"],
1210
+ baseConfidence: "low",
1211
+ baseScore: 0.1
1212
+ };
1213
+ var AU_TFN = {
1214
+ entityType: "AU_TFN",
1215
+ patterns: [
1216
+ /\b\d{3}\s\d{3}\s\d{3}\b/g,
1217
+ /\b\d{9}\b/g
1218
+ ],
1219
+ validate: (match) => {
1220
+ const digits = match.replace(/\s/g, "").split("").map(Number);
1221
+ if (digits.length !== 9) return false;
1222
+ const weights = [1, 4, 3, 7, 5, 8, 6, 9, 10];
1223
+ let sum = 0;
1224
+ for (let i = 0; i < 9; i++) {
1225
+ sum += digits[i] * weights[i];
1226
+ }
1227
+ return sum % 11 === 0;
1228
+ },
1229
+ contextWords: ["tax file number", "tfn"],
1230
+ baseConfidence: "low",
1231
+ baseScore: 0.1
1232
+ };
1233
+ var AU_MEDICARE = {
1234
+ entityType: "AU_MEDICARE",
1235
+ patterns: [
1236
+ /\b[2-6]\d{3}\s\d{5}\s\d\b/g,
1237
+ /\b[2-6]\d{9}\b/g
1238
+ ],
1239
+ validate: (match) => {
1240
+ const digits = match.replace(/\s/g, "").split("").map(Number);
1241
+ if (digits.length !== 10) return false;
1242
+ const weights = [1, 3, 7, 9, 1, 3, 7, 9];
1243
+ let sum = 0;
1244
+ for (let i = 0; i < 8; i++) {
1245
+ sum += digits[i] * weights[i];
1246
+ }
1247
+ return sum % 10 === digits[8];
1248
+ },
1249
+ contextWords: ["medicare"],
1250
+ baseConfidence: "low",
1251
+ baseScore: 0.1
1252
+ };
1253
+ var IN_PAN = {
1254
+ entityType: "IN_PAN",
1255
+ patterns: [
1256
+ /\b[A-Z]{3}[ABCFGHHJLPT][A-Z]\d{4}[A-Z]\b/gi,
1257
+ /\b[A-Z]{5}\d{4}[A-Z]\b/gi
1258
+ ],
1259
+ contextWords: ["permanent account number", "pan"],
1260
+ baseConfidence: "medium",
1261
+ baseScore: 0.5
1262
+ };
1263
+ var IN_AADHAAR = {
1264
+ entityType: "IN_AADHAAR",
1265
+ patterns: [
1266
+ /\b\d{4}[- :]\d{4}[- :]\d{4}\b/g,
1267
+ /\b\d{12}\b/g
1268
+ ],
1269
+ validate: (match) => {
1270
+ const digits = match.replace(/\D/g, "");
1271
+ if (digits.length !== 12) return false;
1272
+ if (parseInt(digits[0], 10) < 2) return false;
1273
+ if (digits === digits.split("").reverse().join("")) return false;
1274
+ return verhoeff(parseInt(digits, 10));
1275
+ },
1276
+ contextWords: ["aadhaar", "uidai"],
1277
+ baseConfidence: "low",
1278
+ baseScore: 0.01
1279
+ };
1280
+ var IN_VEHICLE_REGISTRATION = {
1281
+ entityType: "IN_VEHICLE_REGISTRATION",
1282
+ patterns: [
1283
+ /\b[A-Z]{2}\d{2}[A-Z]{1,2}\d{4}\b/g,
1284
+ /\b[A-Z]{2}\d[A-Z]{1,3}\d{4}\b/g
1285
+ ],
1286
+ contextWords: ["rto", "vehicle", "plate", "registration"],
1287
+ baseConfidence: "medium",
1288
+ baseScore: 0.5
1289
+ };
1290
+ var IN_VOTER = {
1291
+ entityType: "IN_VOTER",
1292
+ patterns: [
1293
+ /\b[A-Z]{3}\d{7}\b/gi
1294
+ ],
1295
+ contextWords: ["voter", "epic", "elector photo identity card"],
1296
+ baseConfidence: "low",
1297
+ baseScore: 0.3
1298
+ };
1299
+ var IN_PASSPORT = {
1300
+ entityType: "IN_PASSPORT",
1301
+ patterns: [/\b[A-Z][1-9]\d\s?\d{4}[1-9]\b/g],
1302
+ contextWords: ["passport", "indian passport", "passport number"],
1303
+ baseConfidence: "low",
1304
+ baseScore: 0.1
1305
+ };
1306
+ var KR_RRN = {
1307
+ entityType: "KR_RRN",
1308
+ patterns: [
1309
+ /(?<!\d)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])-?[1-4]\d{6}(?!\d)/g
1310
+ ],
1311
+ validate: (match) => {
1312
+ const digits = match.replace(/-/g, "");
1313
+ if (digits.length !== 13 || !/^\d+$/.test(digits)) return false;
1314
+ const regionCode = parseInt(digits.slice(7, 9), 10);
1315
+ if (regionCode > 95) return false;
1316
+ const weights = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5];
1317
+ let sum = 0;
1318
+ for (let i = 0; i < 12; i++) {
1319
+ sum += parseInt(digits[i], 10) * weights[i];
1320
+ }
1321
+ const checksum = (11 - sum % 11) % 10;
1322
+ return checksum === parseInt(digits[12], 10);
1323
+ },
1324
+ contextWords: [
1325
+ "resident registration number",
1326
+ "rrn",
1327
+ "korean rrn"
1328
+ ],
1329
+ baseConfidence: "medium",
1330
+ baseScore: 0.5
1331
+ };
1332
+ var KR_PASSPORT = {
1333
+ entityType: "KR_PASSPORT",
1334
+ patterns: [
1335
+ /(?<![A-Z0-9])[MSROD]\d{3}[A-Z]\d{4}(?!\d)/gi,
1336
+ /(?<![A-Z0-9])[MSROD]\d{8}(?!\d)/gi
1337
+ ],
1338
+ contextWords: ["passport", "korean passport", "\uC5EC\uAD8C"],
1339
+ baseConfidence: "low",
1340
+ baseScore: 0.1
1341
+ };
1342
+ var TH_TNIN = {
1343
+ entityType: "TH_TNIN",
1344
+ patterns: [
1345
+ /\b[1-9](?:[134]\d|[25][0134567]|[67][01234567]|[89][0123456])\d{10}\b/g
1346
+ ],
1347
+ validate: (match) => {
1348
+ if (match.length !== 13 || !/^\d+$/.test(match)) return false;
1349
+ const weights = [13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2];
1350
+ let sum = 0;
1351
+ for (let i = 0; i < 12; i++) {
1352
+ sum += weights[i] * parseInt(match[i], 10);
1353
+ }
1354
+ const x = sum % 11;
1355
+ const expected = x <= 1 ? 1 - x : 11 - x;
1356
+ return expected === parseInt(match[12], 10);
1357
+ },
1358
+ contextWords: ["thai national id", "thai id number", "tnin"],
1359
+ baseConfidence: "medium",
1360
+ baseScore: 0.5
1361
+ };
1362
+ var NG_NIN = {
1363
+ entityType: "NG_NIN",
1364
+ patterns: [/\b\d{11}\b/g],
1365
+ validate: (match) => {
1366
+ if (match.length !== 11 || !/^\d+$/.test(match)) return false;
1367
+ return verhoeff(parseInt(match, 10));
1368
+ },
1369
+ contextWords: [
1370
+ "nin",
1371
+ "national identification number",
1372
+ "national identity number",
1373
+ "nimc"
1374
+ ],
1375
+ baseConfidence: "low",
1376
+ baseScore: 0.01
1377
+ };
1378
+ var APAC_PATTERNS = [
1379
+ SG_NRIC_FIN,
1380
+ SG_UEN,
1381
+ AU_ABN,
1382
+ AU_ACN,
1383
+ AU_TFN,
1384
+ AU_MEDICARE,
1385
+ IN_PAN,
1386
+ IN_AADHAAR,
1387
+ IN_VEHICLE_REGISTRATION,
1388
+ IN_VOTER,
1389
+ IN_PASSPORT,
1390
+ KR_RRN,
1391
+ KR_PASSPORT,
1392
+ TH_TNIN,
1393
+ NG_NIN
1394
+ ];
1395
+
1396
+ // src/patterns/pii/index.ts
1397
+ var ALL_PII_PATTERNS = [
1398
+ ...GENERIC_PATTERNS,
1399
+ ...US_PATTERNS,
1400
+ ...UK_PATTERNS,
1401
+ ...EU_PATTERNS,
1402
+ ...APAC_PATTERNS
1403
+ ];
1404
+
1405
+ // src/guards/pii.guard.ts
1406
+ var CONTEXT_WINDOW = 100;
1407
+ var CONTEXT_SCORE_BOOST = 0.35;
1408
+ var PiiGuard = class extends BaseGuard {
1409
+ name = "pii";
1410
+ patterns;
1411
+ constructor(options) {
1412
+ super();
1413
+ let patterns = ALL_PII_PATTERNS;
1414
+ if (options?.entityTypes && options.entityTypes.length > 0) {
1415
+ const allowed = new Set(options.entityTypes);
1416
+ patterns = patterns.filter((p) => allowed.has(p.entityType));
1417
+ }
1418
+ if (options?.customPatterns) {
1419
+ patterns = [...patterns, ...options.customPatterns];
1420
+ }
1421
+ this.patterns = patterns;
1422
+ }
1423
+ async analyze(text, config) {
1424
+ const cfg = this.mergeConfig(config);
1425
+ const detections = this.detectAll(text, cfg.threshold);
1426
+ return this.buildResult(text, detections, cfg.mode);
1427
+ }
1428
+ detectAll(text, threshold) {
1429
+ const allDetections = [];
1430
+ const textLower = text.toLowerCase();
1431
+ for (const pattern of this.patterns) {
1432
+ for (const regex of pattern.patterns) {
1433
+ const re = new RegExp(regex.source, regex.flags);
1434
+ let match;
1435
+ while ((match = re.exec(text)) !== null) {
1436
+ const matchText = match[0];
1437
+ const start = match.index;
1438
+ const end = start + matchText.length;
1439
+ if (pattern.validate && !pattern.validate(matchText)) {
1440
+ continue;
1441
+ }
1442
+ let score = pattern.baseScore;
1443
+ let confidence = pattern.baseConfidence;
1444
+ if (pattern.contextWords && pattern.contextWords.length > 0) {
1445
+ const contextStart = Math.max(0, start - CONTEXT_WINDOW);
1446
+ const contextEnd = Math.min(text.length, end + CONTEXT_WINDOW);
1447
+ const context = textLower.slice(contextStart, contextEnd);
1448
+ const hasContext = pattern.contextWords.some(
1449
+ (word) => context.includes(word.toLowerCase())
1450
+ );
1451
+ if (hasContext) {
1452
+ score = Math.min(1, score + CONTEXT_SCORE_BOOST);
1453
+ if (confidence === "low") confidence = "medium";
1454
+ else if (confidence === "medium") confidence = "high";
1455
+ }
1456
+ }
1457
+ if (score < threshold) continue;
1458
+ allDetections.push(
1459
+ this.makeDetection(text, {
1460
+ entityType: pattern.entityType,
1461
+ start,
1462
+ end,
1463
+ text: matchText,
1464
+ confidence,
1465
+ score,
1466
+ guardName: this.name
1467
+ })
1468
+ );
1469
+ }
1470
+ }
1471
+ }
1472
+ return this.deduplicateDetections(allDetections);
1473
+ }
1474
+ deduplicateDetections(detections) {
1475
+ if (detections.length <= 1) return detections;
1476
+ const sorted = [...detections].sort((a, b) => b.score - a.score);
1477
+ const result = [];
1478
+ for (const detection of sorted) {
1479
+ const overlaps = result.some(
1480
+ (existing) => detection.start < existing.end && detection.end > existing.start
1481
+ );
1482
+ if (!overlaps) {
1483
+ result.push(detection);
1484
+ }
1485
+ }
1486
+ return result.sort((a, b) => a.start - b.start);
1487
+ }
1488
+ };
1489
+
1490
+ // src/patterns/secrets/cloud.ts
1491
+ var AWS_ACCESS_KEY = {
1492
+ secretType: "AWS_ACCESS_KEY",
1493
+ patterns: [/(?<![A-Z0-9])AKIA[0-9A-Z]{16}(?![A-Z0-9])/g]
1494
+ };
1495
+ var AWS_SECRET_KEY = {
1496
+ secretType: "AWS_SECRET_KEY",
1497
+ patterns: [
1498
+ /(?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=])/g
1499
+ ],
1500
+ minEntropy: 4.5
1501
+ };
1502
+ var AWS_SESSION_TOKEN = {
1503
+ secretType: "AWS_SESSION_TOKEN",
1504
+ patterns: [/(?:aws_session_token|AWS_SESSION_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9/+=]{100,})["']?/g],
1505
+ minEntropy: 4
1506
+ };
1507
+ var AWS_MWS_KEY = {
1508
+ secretType: "AWS_MWS_KEY",
1509
+ patterns: [/amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/g]
1510
+ };
1511
+ var AZURE_CONNECTION_STRING = {
1512
+ secretType: "AZURE_CONNECTION_STRING",
1513
+ patterns: [
1514
+ /DefaultEndpointsProtocol=https?;AccountName=[^;]+;AccountKey=[A-Za-z0-9+/=]+;?/g,
1515
+ /(?:AccountKey|SharedAccessKey|SharedAccessSignature)=[A-Za-z0-9+/=]{20,}/g
1516
+ ]
1517
+ };
1518
+ var AZURE_AD_CLIENT_SECRET = {
1519
+ secretType: "AZURE_AD_CLIENT_SECRET",
1520
+ patterns: [/(?:client_secret|AZURE_CLIENT_SECRET)\s*[:=]\s*["']?([A-Za-z0-9~._-]{34,})["']?/g],
1521
+ minEntropy: 3.5
1522
+ };
1523
+ var AZURE_STORAGE_KEY = {
1524
+ secretType: "AZURE_STORAGE_KEY",
1525
+ patterns: [/[A-Za-z0-9+/]{86}==/g],
1526
+ minEntropy: 5
1527
+ };
1528
+ var AZURE_FUNCTION_KEY = {
1529
+ secretType: "AZURE_FUNCTION_KEY",
1530
+ patterns: [/(?:x-functions-key|functionkey)\s*[:=]\s*["']?([A-Za-z0-9_-]{40,})["']?/gi],
1531
+ minEntropy: 3.5
1532
+ };
1533
+ var GCP_SERVICE_ACCOUNT = {
1534
+ secretType: "GCP_SERVICE_ACCOUNT",
1535
+ patterns: [/"private_key"\s*:\s*"-----BEGIN (?:RSA )?PRIVATE KEY-----/g]
1536
+ };
1537
+ var GCP_API_KEY = {
1538
+ secretType: "GCP_API_KEY",
1539
+ patterns: [/AIza[0-9A-Za-z_-]{35}/g]
1540
+ };
1541
+ var GCP_OAUTH_SECRET = {
1542
+ secretType: "GCP_OAUTH_SECRET",
1543
+ patterns: [/GOCSPX-[A-Za-z0-9_-]{28}/g]
1544
+ };
1545
+ var IBM_CLOUD_API_KEY = {
1546
+ secretType: "IBM_CLOUD_API_KEY",
1547
+ patterns: [/(?:ibm[-_]?(?:cloud)?[-_]?api[-_]?key)\s*[:=]\s*["']?([A-Za-z0-9_-]{44})["']?/gi]
1548
+ };
1549
+ var IBM_COS_HMAC = {
1550
+ secretType: "IBM_COS_HMAC",
1551
+ patterns: [/(?:cos_hmac_keys|ibm_cos)\s*[:=]\s*["']?([A-Za-z0-9]{32,})["']?/gi],
1552
+ minEntropy: 3.5
1553
+ };
1554
+ var DIGITALOCEAN_TOKEN = {
1555
+ secretType: "DIGITALOCEAN_TOKEN",
1556
+ patterns: [
1557
+ /dop_v1_[a-f0-9]{64}/g,
1558
+ /doo_v1_[a-f0-9]{64}/g,
1559
+ /dor_v1_[a-f0-9]{64}/g
1560
+ ]
1561
+ };
1562
+ var DIGITALOCEAN_SPACES_KEY = {
1563
+ secretType: "DIGITALOCEAN_SPACES_KEY",
1564
+ patterns: [/(?:SPACES_ACCESS_KEY_ID|DO_SPACES_KEY)\s*[:=]\s*["']?([A-Z0-9]{20})["']?/g]
1565
+ };
1566
+ var LINODE_TOKEN = {
1567
+ secretType: "LINODE_TOKEN",
1568
+ patterns: [/(?:LINODE_TOKEN|LINODE_API_TOKEN)\s*[:=]\s*["']?([a-f0-9]{64})["']?/g]
1569
+ };
1570
+ var VULTR_API_KEY = {
1571
+ secretType: "VULTR_API_KEY",
1572
+ patterns: [/(?:VULTR_API_KEY)\s*[:=]\s*["']?([A-Z0-9]{36})["']?/g]
1573
+ };
1574
+ var ORACLE_CLOUD_KEY = {
1575
+ secretType: "ORACLE_CLOUD_KEY",
1576
+ patterns: [/(?:OCI_API_KEY|ORACLE_CLOUD_KEY)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40,})["']?/g],
1577
+ minEntropy: 4
1578
+ };
1579
+ var ALIBABA_CLOUD_KEY = {
1580
+ secretType: "ALIBABA_CLOUD_KEY",
1581
+ patterns: [/LTAI[A-Za-z0-9]{12,20}/g]
1582
+ };
1583
+ var CLOUD_PATTERNS = [
1584
+ AWS_ACCESS_KEY,
1585
+ AWS_SECRET_KEY,
1586
+ AWS_SESSION_TOKEN,
1587
+ AWS_MWS_KEY,
1588
+ AZURE_CONNECTION_STRING,
1589
+ AZURE_AD_CLIENT_SECRET,
1590
+ AZURE_STORAGE_KEY,
1591
+ AZURE_FUNCTION_KEY,
1592
+ GCP_SERVICE_ACCOUNT,
1593
+ GCP_API_KEY,
1594
+ GCP_OAUTH_SECRET,
1595
+ IBM_CLOUD_API_KEY,
1596
+ IBM_COS_HMAC,
1597
+ DIGITALOCEAN_TOKEN,
1598
+ DIGITALOCEAN_SPACES_KEY,
1599
+ LINODE_TOKEN,
1600
+ VULTR_API_KEY,
1601
+ ORACLE_CLOUD_KEY,
1602
+ ALIBABA_CLOUD_KEY
1603
+ ];
1604
+
1605
+ // src/patterns/secrets/source-control.ts
1606
+ var GITHUB_TOKEN = {
1607
+ secretType: "GITHUB_TOKEN",
1608
+ patterns: [
1609
+ /ghp_[A-Za-z0-9]{36}/g,
1610
+ /gho_[A-Za-z0-9]{36}/g,
1611
+ /ghu_[A-Za-z0-9]{36}/g,
1612
+ /ghs_[A-Za-z0-9]{36}/g,
1613
+ /ghr_[A-Za-z0-9]{36}/g,
1614
+ /github_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{59}/g
1615
+ ]
1616
+ };
1617
+ var GITHUB_APP_TOKEN = {
1618
+ secretType: "GITHUB_APP_TOKEN",
1619
+ patterns: [/(?:ghu|ghs)_[A-Za-z0-9]{36}/g]
1620
+ };
1621
+ var GITHUB_FINE_GRAINED_TOKEN = {
1622
+ secretType: "GITHUB_FINE_GRAINED_TOKEN",
1623
+ patterns: [/github_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{59}/g]
1624
+ };
1625
+ var GITLAB_TOKEN = {
1626
+ secretType: "GITLAB_TOKEN",
1627
+ patterns: [
1628
+ /glpat-[A-Za-z0-9\-_]{20}/g,
1629
+ /glcbt-[A-Za-z0-9]{1,5}_[A-Za-z0-9_\-]{20}/g,
1630
+ /gldt-[A-Za-z0-9_\-]{20}/g,
1631
+ /glft-[A-Za-z0-9_\-]{20}/g,
1632
+ /glsoat-[A-Za-z0-9_\-]{20}/g,
1633
+ /GR1348941[A-Za-z0-9_\-]{20}/g
1634
+ ]
1635
+ };
1636
+ var GITLAB_PIPELINE_TOKEN = {
1637
+ secretType: "GITLAB_PIPELINE_TOKEN",
1638
+ patterns: [/glptt-[A-Za-z0-9]{20}/g]
1639
+ };
1640
+ var BITBUCKET_APP_PASSWORD = {
1641
+ secretType: "BITBUCKET_APP_PASSWORD",
1642
+ patterns: [/(?:BITBUCKET_APP_PASSWORD|BB_APP_PASSWORD)\s*[:=]\s*["']?([A-Za-z0-9]{18,})["']?/g],
1643
+ minEntropy: 3.5
1644
+ };
1645
+ var BITBUCKET_CLIENT_SECRET = {
1646
+ secretType: "BITBUCKET_CLIENT_SECRET",
1647
+ patterns: [/(?:BITBUCKET_CLIENT_SECRET|BB_CLIENT_SECRET)\s*[:=]\s*["']?([A-Za-z0-9_-]{32,})["']?/g],
1648
+ minEntropy: 3.5
1649
+ };
1650
+ var AZURE_DEVOPS_TOKEN = {
1651
+ secretType: "AZURE_DEVOPS_TOKEN",
1652
+ patterns: [/(?:AZURE_DEVOPS_PAT|ADO_TOKEN|SYSTEM_ACCESSTOKEN)\s*[:=]\s*["']?([A-Za-z0-9]{52,})["']?/g],
1653
+ minEntropy: 4
1654
+ };
1655
+ var GITEA_TOKEN = {
1656
+ secretType: "GITEA_TOKEN",
1657
+ patterns: [/(?:GITEA_TOKEN)\s*[:=]\s*["']?([a-f0-9]{40})["']?/g]
1658
+ };
1659
+ var SOURCE_CONTROL_PATTERNS = [
1660
+ GITHUB_TOKEN,
1661
+ GITHUB_APP_TOKEN,
1662
+ GITHUB_FINE_GRAINED_TOKEN,
1663
+ GITLAB_TOKEN,
1664
+ GITLAB_PIPELINE_TOKEN,
1665
+ BITBUCKET_APP_PASSWORD,
1666
+ BITBUCKET_CLIENT_SECRET,
1667
+ AZURE_DEVOPS_TOKEN,
1668
+ GITEA_TOKEN
1669
+ ];
1670
+
1671
+ // src/patterns/secrets/cicd.ts
1672
+ var JENKINS_API_TOKEN = {
1673
+ secretType: "JENKINS_API_TOKEN",
1674
+ patterns: [/(?:JENKINS_TOKEN|JENKINS_API_TOKEN)\s*[:=]\s*["']?([a-f0-9]{32,})["']?/gi]
1675
+ };
1676
+ var JENKINS_CRUMB = {
1677
+ secretType: "JENKINS_CRUMB",
1678
+ patterns: [/Jenkins-Crumb:\s*([a-f0-9]{32,})/g]
1679
+ };
1680
+ var CIRCLECI_TOKEN = {
1681
+ secretType: "CIRCLECI_TOKEN",
1682
+ patterns: [
1683
+ /(?:CIRCLECI_TOKEN|CIRCLE_TOKEN)\s*[:=]\s*["']?([a-f0-9]{40})["']?/g,
1684
+ /circle-token\s*[:=]\s*["']?([a-f0-9]{40})["']?/g
1685
+ ]
1686
+ };
1687
+ var TRAVIS_CI_TOKEN = {
1688
+ secretType: "TRAVIS_CI_TOKEN",
1689
+ patterns: [/(?:TRAVIS_TOKEN|TRAVIS_API_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{20,})["']?/g],
1690
+ minEntropy: 3.5
1691
+ };
1692
+ var GITHUB_ACTIONS_SECRET = {
1693
+ secretType: "GITHUB_ACTIONS_SECRET",
1694
+ patterns: [/(?:ACTIONS_SECRET|GH_ACTION_SECRET)\s*[:=]\s*["']?([A-Za-z0-9_-]{20,})["']?/g],
1695
+ minEntropy: 3.5
1696
+ };
1697
+ var BUILDKITE_TOKEN = {
1698
+ secretType: "BUILDKITE_TOKEN",
1699
+ patterns: [/bkua_[A-Za-z0-9]{40}/g]
1700
+ };
1701
+ var BUILDKITE_AGENT_TOKEN = {
1702
+ secretType: "BUILDKITE_AGENT_TOKEN",
1703
+ patterns: [/(?:BUILDKITE_AGENT_TOKEN)\s*[:=]\s*["']?([a-f0-9]{40,})["']?/g]
1704
+ };
1705
+ var DRONE_CI_TOKEN = {
1706
+ secretType: "DRONE_CI_TOKEN",
1707
+ patterns: [/(?:DRONE_TOKEN|DRONE_SERVER_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9]{32,})["']?/g],
1708
+ minEntropy: 3.5
1709
+ };
1710
+ var CODECOV_TOKEN = {
1711
+ secretType: "CODECOV_TOKEN",
1712
+ patterns: [/(?:CODECOV_TOKEN)\s*[:=]\s*["']?([a-f0-9-]{36})["']?/g]
1713
+ };
1714
+ var SONARQUBE_TOKEN = {
1715
+ secretType: "SONARQUBE_TOKEN",
1716
+ patterns: [
1717
+ /squ_[A-Za-z0-9]{40}/g,
1718
+ /sqp_[A-Za-z0-9]{40}/g
1719
+ ]
1720
+ };
1721
+ var TEAMCITY_TOKEN = {
1722
+ secretType: "TEAMCITY_TOKEN",
1723
+ patterns: [/(?:TEAMCITY_TOKEN|TC_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{20,})["']?/g],
1724
+ minEntropy: 3.5
1725
+ };
1726
+ var CICD_PATTERNS = [
1727
+ JENKINS_API_TOKEN,
1728
+ JENKINS_CRUMB,
1729
+ CIRCLECI_TOKEN,
1730
+ TRAVIS_CI_TOKEN,
1731
+ GITHUB_ACTIONS_SECRET,
1732
+ BUILDKITE_TOKEN,
1733
+ BUILDKITE_AGENT_TOKEN,
1734
+ DRONE_CI_TOKEN,
1735
+ CODECOV_TOKEN,
1736
+ SONARQUBE_TOKEN,
1737
+ TEAMCITY_TOKEN
1738
+ ];
1739
+
1740
+ // src/patterns/secrets/communication.ts
1741
+ var SLACK_TOKEN = {
1742
+ secretType: "SLACK_TOKEN",
1743
+ patterns: [/xox[bporas]-[A-Za-z0-9-]{10,}/g]
1744
+ };
1745
+ var SLACK_WEBHOOK = {
1746
+ secretType: "SLACK_WEBHOOK",
1747
+ patterns: [/https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]{8,}\/B[A-Z0-9]{8,}\/[A-Za-z0-9]{24}/g]
1748
+ };
1749
+ var SLACK_APP_TOKEN = {
1750
+ secretType: "SLACK_APP_TOKEN",
1751
+ patterns: [/xapp-[0-9]+-[A-Za-z0-9]+-[0-9]+-[A-Za-z0-9]+/g]
1752
+ };
1753
+ var DISCORD_TOKEN = {
1754
+ secretType: "DISCORD_TOKEN",
1755
+ patterns: [/(?:DISCORD_TOKEN|DISCORD_BOT_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{24}\.[A-Za-z0-9_-]{6}\.[A-Za-z0-9_-]{27,})["']?/g]
1756
+ };
1757
+ var DISCORD_WEBHOOK = {
1758
+ secretType: "DISCORD_WEBHOOK",
1759
+ patterns: [/https:\/\/(?:ptb\.|canary\.)?discord(?:app)?\.com\/api\/webhooks\/\d+\/[A-Za-z0-9_-]+/g]
1760
+ };
1761
+ var TELEGRAM_BOT_TOKEN = {
1762
+ secretType: "TELEGRAM_BOT_TOKEN",
1763
+ patterns: [/[0-9]{8,10}:[A-Za-z0-9_-]{35}/g]
1764
+ };
1765
+ var TWILIO_KEY = {
1766
+ secretType: "TWILIO_KEY",
1767
+ patterns: [/SK[0-9a-fA-F]{32}/g]
1768
+ };
1769
+ var TWILIO_ACCOUNT_SID = {
1770
+ secretType: "TWILIO_ACCOUNT_SID",
1771
+ patterns: [/AC[a-f0-9]{32}/g]
1772
+ };
1773
+ var TWILIO_AUTH_TOKEN = {
1774
+ secretType: "TWILIO_AUTH_TOKEN",
1775
+ patterns: [/(?:TWILIO_AUTH_TOKEN)\s*[:=]\s*["']?([a-f0-9]{32})["']?/g]
1776
+ };
1777
+ var SENDGRID_KEY = {
1778
+ secretType: "SENDGRID_KEY",
1779
+ patterns: [/SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}/g]
1780
+ };
1781
+ var MAILGUN_KEY = {
1782
+ secretType: "MAILGUN_KEY",
1783
+ patterns: [
1784
+ /key-[A-Za-z0-9]{32}/g,
1785
+ /(?:MAILGUN_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9-]{32,})["']?/g
1786
+ ]
1787
+ };
1788
+ var MAILCHIMP_KEY = {
1789
+ secretType: "MAILCHIMP_KEY",
1790
+ patterns: [/[a-f0-9]{32}-us[0-9]{1,2}/g]
1791
+ };
1792
+ var POSTMARK_TOKEN = {
1793
+ secretType: "POSTMARK_TOKEN",
1794
+ patterns: [/(?:POSTMARK_API_TOKEN|POSTMARK_SERVER_TOKEN)\s*[:=]\s*["']?([a-f0-9-]{36})["']?/g]
1795
+ };
1796
+ var TEAMS_WEBHOOK = {
1797
+ secretType: "TEAMS_WEBHOOK",
1798
+ patterns: [/https:\/\/[a-z0-9-]+\.webhook\.office\.com\/webhookb2\/[A-Za-z0-9-]+/g]
1799
+ };
1800
+ var INTERCOM_TOKEN = {
1801
+ secretType: "INTERCOM_TOKEN",
1802
+ patterns: [/(?:INTERCOM_TOKEN|INTERCOM_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9_=-]{20,})["']?/g],
1803
+ minEntropy: 3.5
1804
+ };
1805
+ var COMMUNICATION_PATTERNS = [
1806
+ SLACK_TOKEN,
1807
+ SLACK_WEBHOOK,
1808
+ SLACK_APP_TOKEN,
1809
+ DISCORD_TOKEN,
1810
+ DISCORD_WEBHOOK,
1811
+ TELEGRAM_BOT_TOKEN,
1812
+ TWILIO_KEY,
1813
+ TWILIO_ACCOUNT_SID,
1814
+ TWILIO_AUTH_TOKEN,
1815
+ SENDGRID_KEY,
1816
+ MAILGUN_KEY,
1817
+ MAILCHIMP_KEY,
1818
+ POSTMARK_TOKEN,
1819
+ TEAMS_WEBHOOK,
1820
+ INTERCOM_TOKEN
1821
+ ];
1822
+
1823
+ // src/patterns/secrets/payment.ts
1824
+ var STRIPE_KEY = {
1825
+ secretType: "STRIPE_KEY",
1826
+ patterns: [
1827
+ /sk_live_[A-Za-z0-9]{20,}/g,
1828
+ /rk_live_[A-Za-z0-9]{20,}/g,
1829
+ /sk_test_[A-Za-z0-9]{20,}/g,
1830
+ /rk_test_[A-Za-z0-9]{20,}/g
1831
+ ]
1832
+ };
1833
+ var STRIPE_WEBHOOK_SECRET = {
1834
+ secretType: "STRIPE_WEBHOOK_SECRET",
1835
+ patterns: [/whsec_[A-Za-z0-9]{32,}/g]
1836
+ };
1837
+ var SQUARE_ACCESS_TOKEN = {
1838
+ secretType: "SQUARE_ACCESS_TOKEN",
1839
+ patterns: [
1840
+ /sq0atp-[A-Za-z0-9_-]{22}/g,
1841
+ /EAAAE[A-Za-z0-9]{50,}/g
1842
+ ]
1843
+ };
1844
+ var SQUARE_OAUTH_SECRET = {
1845
+ secretType: "SQUARE_OAUTH_SECRET",
1846
+ patterns: [/sq0csp-[A-Za-z0-9_-]{43}/g]
1847
+ };
1848
+ var PAYPAL_CLIENT_SECRET = {
1849
+ secretType: "PAYPAL_CLIENT_SECRET",
1850
+ patterns: [/(?:PAYPAL_CLIENT_SECRET|PAYPAL_SECRET)\s*[:=]\s*["']?([A-Za-z0-9_-]{40,})["']?/g],
1851
+ minEntropy: 3.5
1852
+ };
1853
+ var PAYPAL_BRAINTREE_TOKEN = {
1854
+ secretType: "PAYPAL_BRAINTREE_TOKEN",
1855
+ patterns: [/access_token\$(?:production|sandbox)\$[a-z0-9]{16}\$[a-f0-9]{32}/g]
1856
+ };
1857
+ var BRAINTREE_KEY = {
1858
+ secretType: "BRAINTREE_KEY",
1859
+ patterns: [/(?:BRAINTREE_(?:PUBLIC|PRIVATE)_KEY)\s*[:=]\s*["']?([A-Za-z0-9]{32})["']?/g]
1860
+ };
1861
+ var ADYEN_API_KEY = {
1862
+ secretType: "ADYEN_API_KEY",
1863
+ patterns: [/(?:ADYEN_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9]{32,})["']?/g],
1864
+ minEntropy: 3.5
1865
+ };
1866
+ var SHOPIFY_TOKEN = {
1867
+ secretType: "SHOPIFY_TOKEN",
1868
+ patterns: [
1869
+ /shpat_[a-fA-F0-9]{32}/g,
1870
+ /shpca_[a-fA-F0-9]{32}/g,
1871
+ /shppa_[a-fA-F0-9]{32}/g,
1872
+ /shpss_[a-fA-F0-9]{32}/g
1873
+ ]
1874
+ };
1875
+ var PLAID_KEY = {
1876
+ secretType: "PLAID_KEY",
1877
+ patterns: [
1878
+ /(?:PLAID_CLIENT_ID)\s*[:=]\s*["']?([a-f0-9]{24})["']?/g,
1879
+ /(?:PLAID_SECRET)\s*[:=]\s*["']?([a-f0-9]{30})["']?/g,
1880
+ /access-(?:sandbox|development|production)-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g
1881
+ ]
1882
+ };
1883
+ var PAYMENT_PATTERNS = [
1884
+ STRIPE_KEY,
1885
+ STRIPE_WEBHOOK_SECRET,
1886
+ SQUARE_ACCESS_TOKEN,
1887
+ SQUARE_OAUTH_SECRET,
1888
+ PAYPAL_CLIENT_SECRET,
1889
+ PAYPAL_BRAINTREE_TOKEN,
1890
+ BRAINTREE_KEY,
1891
+ ADYEN_API_KEY,
1892
+ SHOPIFY_TOKEN,
1893
+ PLAID_KEY
1894
+ ];
1895
+
1896
+ // src/patterns/secrets/database.ts
1897
+ var DATABASE_CONNECTION_STRING = {
1898
+ secretType: "DATABASE_CONNECTION_STRING",
1899
+ patterns: [
1900
+ /(?:postgres|postgresql|mysql|mongodb|redis|amqp|mssql):\/\/[^\s"']+/gi
1901
+ ]
1902
+ };
1903
+ var MONGODB_SRV = {
1904
+ secretType: "MONGODB_SRV",
1905
+ patterns: [/mongodb\+srv:\/\/[^\s"']+/g]
1906
+ };
1907
+ var REDIS_URL_WITH_PASSWORD = {
1908
+ secretType: "REDIS_URL_WITH_PASSWORD",
1909
+ patterns: [/redis:\/\/:[^@\s]+@[^\s"']+/g]
1910
+ };
1911
+ var ELASTICSEARCH_URL = {
1912
+ secretType: "ELASTICSEARCH_URL",
1913
+ patterns: [/https?:\/\/[^:]+:[^@]+@[^/]*(?:elastic|es|elasticsearch)[^\s"']*/gi]
1914
+ };
1915
+ var FIREBASE_KEY = {
1916
+ secretType: "FIREBASE_KEY",
1917
+ patterns: [/(?:FIREBASE_API_KEY|FIREBASE_KEY)\s*[:=]\s*["']?(AIza[A-Za-z0-9_-]{35})["']?/g]
1918
+ };
1919
+ var FIREBASE_URL = {
1920
+ secretType: "FIREBASE_URL",
1921
+ patterns: [/https:\/\/[a-z0-9-]+\.firebaseio\.com/g]
1922
+ };
1923
+ var SUPABASE_KEY = {
1924
+ secretType: "SUPABASE_KEY",
1925
+ patterns: [
1926
+ /(?:SUPABASE_KEY|SUPABASE_ANON_KEY|SUPABASE_SERVICE_KEY)\s*[:=]\s*["']?(eyJ[A-Za-z0-9_-]{100,})["']?/g
1927
+ ]
1928
+ };
1929
+ var PLANETSCALE_TOKEN = {
1930
+ secretType: "PLANETSCALE_TOKEN",
1931
+ patterns: [/pscale_tkn_[A-Za-z0-9_-]{40,}/g]
1932
+ };
1933
+ var PLANETSCALE_PASSWORD = {
1934
+ secretType: "PLANETSCALE_PASSWORD",
1935
+ patterns: [/pscale_pw_[A-Za-z0-9_-]{40,}/g]
1936
+ };
1937
+ var COCKROACHDB_CONNECTION = {
1938
+ secretType: "COCKROACHDB_CONNECTION",
1939
+ patterns: [/(?:COCKROACH_URL|DATABASE_URL)\s*[:=]\s*["']?(postgresql:\/\/[^\s"']+\.cockroachlabs\.cloud[^\s"']*)["']?/g]
1940
+ };
1941
+ var NEON_DB_TOKEN = {
1942
+ secretType: "NEON_DB_TOKEN",
1943
+ patterns: [/(?:NEON_API_KEY|NEON_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{40,})["']?/g],
1944
+ minEntropy: 3.5
1945
+ };
1946
+ var DATABASE_PATTERNS = [
1947
+ DATABASE_CONNECTION_STRING,
1948
+ MONGODB_SRV,
1949
+ REDIS_URL_WITH_PASSWORD,
1950
+ ELASTICSEARCH_URL,
1951
+ FIREBASE_KEY,
1952
+ FIREBASE_URL,
1953
+ SUPABASE_KEY,
1954
+ PLANETSCALE_TOKEN,
1955
+ PLANETSCALE_PASSWORD,
1956
+ COCKROACHDB_CONNECTION,
1957
+ NEON_DB_TOKEN
1958
+ ];
1959
+
1960
+ // src/patterns/secrets/infrastructure.ts
1961
+ var DOCKER_HUB_TOKEN = {
1962
+ secretType: "DOCKER_HUB_TOKEN",
1963
+ patterns: [
1964
+ /dckr_pat_[A-Za-z0-9_-]{27,}/g,
1965
+ /(?:DOCKER_PASSWORD|DOCKERHUB_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{36,})["']?/g
1966
+ ]
1967
+ };
1968
+ var DOCKER_REGISTRY_AUTH = {
1969
+ secretType: "DOCKER_REGISTRY_AUTH",
1970
+ patterns: [/"auth"\s*:\s*"([A-Za-z0-9+/=]{20,})"/g],
1971
+ minEntropy: 3.5
1972
+ };
1973
+ var KUBERNETES_SERVICE_TOKEN = {
1974
+ secretType: "KUBERNETES_SERVICE_TOKEN",
1975
+ patterns: [/(?:KUBERNETES_TOKEN|K8S_TOKEN|KUBE_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{100,})["']?/g],
1976
+ minEntropy: 4
1977
+ };
1978
+ var TERRAFORM_TOKEN = {
1979
+ secretType: "TERRAFORM_TOKEN",
1980
+ patterns: [
1981
+ /[A-Za-z0-9]{14}\.atlasv1\.[A-Za-z0-9_-]{60,}/g,
1982
+ /(?:TF_TOKEN|TFC_TOKEN|TERRAFORM_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9._-]{40,})["']?/g
1983
+ ]
1984
+ };
1985
+ var VAULT_TOKEN = {
1986
+ secretType: "VAULT_TOKEN",
1987
+ patterns: [
1988
+ /hvs\.[A-Za-z0-9_-]{24,}/g,
1989
+ /(?:VAULT_TOKEN)\s*[:=]\s*["']?([a-z0-9.-]{20,})["']?/g
1990
+ ]
1991
+ };
1992
+ var CONSUL_TOKEN = {
1993
+ secretType: "CONSUL_TOKEN",
1994
+ patterns: [/(?:CONSUL_TOKEN|CONSUL_HTTP_TOKEN)\s*[:=]\s*["']?([a-f0-9-]{36})["']?/g]
1995
+ };
1996
+ var PULUMI_TOKEN = {
1997
+ secretType: "PULUMI_TOKEN",
1998
+ patterns: [/pul-[A-Za-z0-9]{40}/g]
1999
+ };
2000
+ var ANSIBLE_VAULT_PASSWORD = {
2001
+ secretType: "ANSIBLE_VAULT_PASSWORD",
2002
+ patterns: [/\$ANSIBLE_VAULT;[0-9.]+;AES256/g]
2003
+ };
2004
+ var HELM_REPO_TOKEN = {
2005
+ secretType: "HELM_REPO_TOKEN",
2006
+ patterns: [/(?:HELM_REPO_PASSWORD|HELM_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{20,})["']?/g],
2007
+ minEntropy: 3.5
2008
+ };
2009
+ var GRAFANA_API_KEY = {
2010
+ secretType: "GRAFANA_API_KEY",
2011
+ patterns: [
2012
+ /eyJrIjoi[A-Za-z0-9_-]{30,}/g,
2013
+ /glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8}/g,
2014
+ /glc_[A-Za-z0-9+/]{32,}={0,2}/g
2015
+ ]
2016
+ };
2017
+ var INFRASTRUCTURE_PATTERNS = [
2018
+ DOCKER_HUB_TOKEN,
2019
+ DOCKER_REGISTRY_AUTH,
2020
+ KUBERNETES_SERVICE_TOKEN,
2021
+ TERRAFORM_TOKEN,
2022
+ VAULT_TOKEN,
2023
+ CONSUL_TOKEN,
2024
+ PULUMI_TOKEN,
2025
+ ANSIBLE_VAULT_PASSWORD,
2026
+ HELM_REPO_TOKEN,
2027
+ GRAFANA_API_KEY
2028
+ ];
2029
+
2030
+ // src/patterns/secrets/saas.ts
2031
+ var SALESFORCE_TOKEN = {
2032
+ secretType: "SALESFORCE_TOKEN",
2033
+ patterns: [/(?:SALESFORCE_TOKEN|SF_ACCESS_TOKEN|SFDC_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9!]{40,})["']?/g],
2034
+ minEntropy: 3.5
2035
+ };
2036
+ var HUBSPOT_API_KEY = {
2037
+ secretType: "HUBSPOT_API_KEY",
2038
+ patterns: [
2039
+ /(?:HUBSPOT_API_KEY|HAPI_KEY)\s*[:=]\s*["']?([a-f0-9-]{36})["']?/g,
2040
+ /pat-(?:na|eu)1-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g
2041
+ ]
2042
+ };
2043
+ var ZENDESK_TOKEN = {
2044
+ secretType: "ZENDESK_TOKEN",
2045
+ patterns: [/(?:ZENDESK_TOKEN|ZENDESK_API_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9]{40})["']?/g]
2046
+ };
2047
+ var DATADOG_API_KEY = {
2048
+ secretType: "DATADOG_API_KEY",
2049
+ patterns: [
2050
+ /(?:DD_API_KEY|DATADOG_API_KEY)\s*[:=]\s*["']?([a-f0-9]{32})["']?/g,
2051
+ /(?:DD_APP_KEY|DATADOG_APP_KEY)\s*[:=]\s*["']?([a-f0-9]{40})["']?/g
2052
+ ]
2053
+ };
2054
+ var NEW_RELIC_KEY = {
2055
+ secretType: "NEW_RELIC_KEY",
2056
+ patterns: [
2057
+ /NRAK-[A-Z0-9]{27}/g,
2058
+ /(?:NEW_RELIC_LICENSE_KEY|NEWRELIC_KEY)\s*[:=]\s*["']?([a-f0-9]{40})["']?/g,
2059
+ /NRII-[A-Za-z0-9_-]{32}/g,
2060
+ /NRIQ-[A-Za-z0-9_-]{32}/g
2061
+ ]
2062
+ };
2063
+ var PAGERDUTY_KEY = {
2064
+ secretType: "PAGERDUTY_KEY",
2065
+ patterns: [/(?:PAGERDUTY_TOKEN|PD_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9_+-]{20})["']?/g]
2066
+ };
2067
+ var LAUNCHDARKLY_KEY = {
2068
+ secretType: "LAUNCHDARKLY_KEY",
2069
+ patterns: [
2070
+ /(?:sdk|mob|api)-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g
2071
+ ]
2072
+ };
2073
+ var SENTRY_DSN = {
2074
+ secretType: "SENTRY_DSN",
2075
+ patterns: [/https:\/\/[a-f0-9]{32}@[a-z0-9.]+\.ingest\.sentry\.io\/[0-9]+/g]
2076
+ };
2077
+ var SENTRY_AUTH_TOKEN = {
2078
+ secretType: "SENTRY_AUTH_TOKEN",
2079
+ patterns: [
2080
+ /sntrys_[A-Za-z0-9]{60,}/g,
2081
+ /(?:SENTRY_AUTH_TOKEN)\s*[:=]\s*["']?([a-f0-9]{64})["']?/g
2082
+ ]
2083
+ };
2084
+ var SEGMENT_KEY = {
2085
+ secretType: "SEGMENT_KEY",
2086
+ patterns: [/(?:SEGMENT_WRITE_KEY|SEGMENT_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9]{32})["']?/g]
2087
+ };
2088
+ var AIRTABLE_KEY = {
2089
+ secretType: "AIRTABLE_KEY",
2090
+ patterns: [
2091
+ /key[A-Za-z0-9]{14}/g,
2092
+ /pat[A-Za-z0-9]{14}\.[a-f0-9]{64}/g
2093
+ ]
2094
+ };
2095
+ var NOTION_TOKEN = {
2096
+ secretType: "NOTION_TOKEN",
2097
+ patterns: [
2098
+ /secret_[A-Za-z0-9]{43}/g,
2099
+ /ntn_[A-Za-z0-9]{40,}/g
2100
+ ]
2101
+ };
2102
+ var ASANA_TOKEN = {
2103
+ secretType: "ASANA_TOKEN",
2104
+ patterns: [/(?:ASANA_TOKEN|ASANA_ACCESS_TOKEN)\s*[:=]\s*["']?([0-9]\/[0-9]{16}:[A-Za-z0-9]{32})["']?/g]
2105
+ };
2106
+ var JIRA_TOKEN = {
2107
+ secretType: "JIRA_TOKEN",
2108
+ patterns: [/(?:JIRA_TOKEN|JIRA_API_TOKEN|ATLASSIAN_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9]{24,})["']?/g],
2109
+ minEntropy: 3.5
2110
+ };
2111
+ var LINEAR_API_KEY = {
2112
+ secretType: "LINEAR_API_KEY",
2113
+ patterns: [/lin_api_[A-Za-z0-9]{40}/g]
2114
+ };
2115
+ var CONTENTFUL_TOKEN = {
2116
+ secretType: "CONTENTFUL_TOKEN",
2117
+ patterns: [/(?:CONTENTFUL_ACCESS_TOKEN|CONTENTFUL_DELIVERY_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{43})["']?/g]
2118
+ };
2119
+ var ALGOLIA_KEY = {
2120
+ secretType: "ALGOLIA_KEY",
2121
+ patterns: [/(?:ALGOLIA_ADMIN_KEY|ALGOLIA_API_KEY)\s*[:=]\s*["']?([a-f0-9]{32})["']?/g]
2122
+ };
2123
+ var SAAS_PATTERNS = [
2124
+ SALESFORCE_TOKEN,
2125
+ HUBSPOT_API_KEY,
2126
+ ZENDESK_TOKEN,
2127
+ DATADOG_API_KEY,
2128
+ NEW_RELIC_KEY,
2129
+ PAGERDUTY_KEY,
2130
+ LAUNCHDARKLY_KEY,
2131
+ SENTRY_DSN,
2132
+ SENTRY_AUTH_TOKEN,
2133
+ SEGMENT_KEY,
2134
+ AIRTABLE_KEY,
2135
+ NOTION_TOKEN,
2136
+ ASANA_TOKEN,
2137
+ JIRA_TOKEN,
2138
+ LINEAR_API_KEY,
2139
+ CONTENTFUL_TOKEN,
2140
+ ALGOLIA_KEY
2141
+ ];
2142
+
2143
+ // src/patterns/secrets/ai-ml.ts
2144
+ var OPENAI_KEY = {
2145
+ secretType: "OPENAI_KEY",
2146
+ patterns: [
2147
+ /sk-[A-Za-z0-9]{20}T3BlbkFJ[A-Za-z0-9]{20}/g,
2148
+ /sk-proj-[A-Za-z0-9_-]{40,}/g,
2149
+ /sk-[A-Za-z0-9_-]{40,}/g
2150
+ ]
2151
+ };
2152
+ var ANTHROPIC_KEY = {
2153
+ secretType: "ANTHROPIC_KEY",
2154
+ patterns: [/sk-ant-[A-Za-z0-9_-]{40,}/g]
2155
+ };
2156
+ var COHERE_KEY = {
2157
+ secretType: "COHERE_KEY",
2158
+ patterns: [
2159
+ /(?:COHERE_API_KEY|CO_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9]{40})["']?/g
2160
+ ]
2161
+ };
2162
+ var HUGGINGFACE_TOKEN = {
2163
+ secretType: "HUGGINGFACE_TOKEN",
2164
+ patterns: [/hf_[A-Za-z0-9]{34}/g]
2165
+ };
2166
+ var REPLICATE_TOKEN = {
2167
+ secretType: "REPLICATE_TOKEN",
2168
+ patterns: [
2169
+ /r8_[A-Za-z0-9]{37}/g,
2170
+ /(?:REPLICATE_API_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{40})["']?/g
2171
+ ]
2172
+ };
2173
+ var GOOGLE_AI_KEY = {
2174
+ secretType: "GOOGLE_AI_KEY",
2175
+ patterns: [/(?:GOOGLE_AI_KEY|GEMINI_API_KEY)\s*[:=]\s*["']?(AIza[A-Za-z0-9_-]{35})["']?/g]
2176
+ };
2177
+ var MISTRAL_KEY = {
2178
+ secretType: "MISTRAL_KEY",
2179
+ patterns: [/(?:MISTRAL_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9]{32})["']?/g]
2180
+ };
2181
+ var PINECONE_KEY = {
2182
+ secretType: "PINECONE_KEY",
2183
+ patterns: [/(?:PINECONE_API_KEY)\s*[:=]\s*["']?([a-f0-9-]{36})["']?/g]
2184
+ };
2185
+ var WEAVIATE_KEY = {
2186
+ secretType: "WEAVIATE_KEY",
2187
+ patterns: [/(?:WEAVIATE_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9]{40,})["']?/g],
2188
+ minEntropy: 3.5
2189
+ };
2190
+ var WANDB_KEY = {
2191
+ secretType: "WANDB_KEY",
2192
+ patterns: [/(?:WANDB_API_KEY)\s*[:=]\s*["']?([a-f0-9]{40})["']?/g]
2193
+ };
2194
+ var DEEPSEEK_KEY = {
2195
+ secretType: "DEEPSEEK_KEY",
2196
+ patterns: [/(?:DEEPSEEK_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9_-]{40,})["']?/g],
2197
+ minEntropy: 3.5
2198
+ };
2199
+ var GROQ_KEY = {
2200
+ secretType: "GROQ_KEY",
2201
+ patterns: [/gsk_[A-Za-z0-9]{52}/g]
2202
+ };
2203
+ var AI_ML_PATTERNS = [
2204
+ OPENAI_KEY,
2205
+ ANTHROPIC_KEY,
2206
+ COHERE_KEY,
2207
+ HUGGINGFACE_TOKEN,
2208
+ REPLICATE_TOKEN,
2209
+ GOOGLE_AI_KEY,
2210
+ MISTRAL_KEY,
2211
+ PINECONE_KEY,
2212
+ WEAVIATE_KEY,
2213
+ WANDB_KEY,
2214
+ DEEPSEEK_KEY,
2215
+ GROQ_KEY
2216
+ ];
2217
+
2218
+ // src/patterns/secrets/auth.ts
2219
+ var AUTH0_CLIENT_SECRET = {
2220
+ secretType: "AUTH0_CLIENT_SECRET",
2221
+ patterns: [/(?:AUTH0_CLIENT_SECRET)\s*[:=]\s*["']?([A-Za-z0-9_-]{32,})["']?/g],
2222
+ minEntropy: 3.5
2223
+ };
2224
+ var AUTH0_MANAGEMENT_TOKEN = {
2225
+ secretType: "AUTH0_MANAGEMENT_TOKEN",
2226
+ patterns: [/(?:AUTH0_MANAGEMENT_API_TOKEN|AUTH0_TOKEN)\s*[:=]\s*["']?(eyJ[A-Za-z0-9_-]{100,})["']?/g]
2227
+ };
2228
+ var OKTA_TOKEN = {
2229
+ secretType: "OKTA_TOKEN",
2230
+ patterns: [
2231
+ /(?:OKTA_TOKEN|OKTA_API_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{42})["']?/g,
2232
+ /00[A-Za-z0-9_-]{40}/g
2233
+ ]
2234
+ };
2235
+ var CLERK_SECRET_KEY = {
2236
+ secretType: "CLERK_SECRET_KEY",
2237
+ patterns: [/sk_(?:live|test)_[A-Za-z0-9]{24,}/g]
2238
+ };
2239
+ var CLERK_PUBLISHABLE_KEY = {
2240
+ secretType: "CLERK_PUBLISHABLE_KEY",
2241
+ patterns: [/pk_(?:live|test)_[A-Za-z0-9]{24,}/g]
2242
+ };
2243
+ var FIREBASE_AUTH_KEY = {
2244
+ secretType: "FIREBASE_AUTH_KEY",
2245
+ patterns: [/(?:FIREBASE_AUTH_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{100,})["']?/g],
2246
+ minEntropy: 4
2247
+ };
2248
+ var SUPABASE_SERVICE_KEY = {
2249
+ secretType: "SUPABASE_SERVICE_KEY",
2250
+ patterns: [/(?:SUPABASE_SERVICE_ROLE_KEY)\s*[:=]\s*["']?(eyJ[A-Za-z0-9_-]{100,})["']?/g]
2251
+ };
2252
+ var STYTCH_SECRET = {
2253
+ secretType: "STYTCH_SECRET",
2254
+ patterns: [/secret-(?:live|test)-[A-Za-z0-9_-]{36,}/g]
2255
+ };
2256
+ var PROPELAUTH_KEY = {
2257
+ secretType: "PROPELAUTH_KEY",
2258
+ patterns: [/(?:PROPELAUTH_API_KEY)\s*[:=]\s*["']?([A-Za-z0-9_-]{40,})["']?/g],
2259
+ minEntropy: 3.5
2260
+ };
2261
+ var KEYCLOAK_SECRET = {
2262
+ secretType: "KEYCLOAK_SECRET",
2263
+ patterns: [/(?:KEYCLOAK_CLIENT_SECRET|KC_CLIENT_SECRET)\s*[:=]\s*["']?([A-Za-z0-9-]{36})["']?/g]
2264
+ };
2265
+ var AUTH_PATTERNS = [
2266
+ AUTH0_CLIENT_SECRET,
2267
+ AUTH0_MANAGEMENT_TOKEN,
2268
+ OKTA_TOKEN,
2269
+ CLERK_SECRET_KEY,
2270
+ CLERK_PUBLISHABLE_KEY,
2271
+ FIREBASE_AUTH_KEY,
2272
+ SUPABASE_SERVICE_KEY,
2273
+ STYTCH_SECRET,
2274
+ PROPELAUTH_KEY,
2275
+ KEYCLOAK_SECRET
2276
+ ];
2277
+
2278
+ // src/patterns/secrets/cdn-hosting.ts
2279
+ var CLOUDFLARE_API_KEY = {
2280
+ secretType: "CLOUDFLARE_API_KEY",
2281
+ patterns: [
2282
+ /(?:CLOUDFLARE_API_KEY|CF_API_KEY)\s*[:=]\s*["']?([a-f0-9]{37})["']?/g,
2283
+ /(?:CLOUDFLARE_API_TOKEN|CF_API_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{40})["']?/g
2284
+ ]
2285
+ };
2286
+ var CLOUDFLARE_CA_KEY = {
2287
+ secretType: "CLOUDFLARE_CA_KEY",
2288
+ patterns: [/v1\.0-[a-f0-9]{24}-[a-f0-9]{146}/g]
2289
+ };
2290
+ var FASTLY_API_KEY = {
2291
+ secretType: "FASTLY_API_KEY",
2292
+ patterns: [/(?:FASTLY_API_TOKEN|FASTLY_KEY)\s*[:=]\s*["']?([A-Za-z0-9_-]{32})["']?/g]
2293
+ };
2294
+ var NETLIFY_TOKEN = {
2295
+ secretType: "NETLIFY_TOKEN",
2296
+ patterns: [/(?:NETLIFY_AUTH_TOKEN|NETLIFY_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{40,})["']?/g],
2297
+ minEntropy: 3.5
2298
+ };
2299
+ var VERCEL_TOKEN = {
2300
+ secretType: "VERCEL_TOKEN",
2301
+ patterns: [/(?:VERCEL_TOKEN|NOW_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9]{24})["']?/g]
2302
+ };
2303
+ var HEROKU_API_KEY = {
2304
+ secretType: "HEROKU_API_KEY",
2305
+ patterns: [
2306
+ /(?:HEROKU_API_KEY)\s*[:=]\s*["']?([a-f0-9-]{36})["']?/g,
2307
+ /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g
2308
+ ]
2309
+ };
2310
+ var RENDER_TOKEN = {
2311
+ secretType: "RENDER_TOKEN",
2312
+ patterns: [/rnd_[A-Za-z0-9]{32,}/g]
2313
+ };
2314
+ var FLY_IO_TOKEN = {
2315
+ secretType: "FLY_IO_TOKEN",
2316
+ patterns: [/(?:FLY_ACCESS_TOKEN|FLY_API_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{40,})["']?/g],
2317
+ minEntropy: 3.5
2318
+ };
2319
+ var RAILWAY_TOKEN = {
2320
+ secretType: "RAILWAY_TOKEN",
2321
+ patterns: [/(?:RAILWAY_TOKEN)\s*[:=]\s*["']?([a-f0-9-]{36})["']?/g]
2322
+ };
2323
+ var SURGE_TOKEN = {
2324
+ secretType: "SURGE_TOKEN",
2325
+ patterns: [/(?:SURGE_TOKEN|SURGE_LOGIN)\s*[:=]\s*["']?([A-Za-z0-9._-]{20,})["']?/g],
2326
+ minEntropy: 3.5
2327
+ };
2328
+ var CDN_HOSTING_PATTERNS = [
2329
+ CLOUDFLARE_API_KEY,
2330
+ CLOUDFLARE_CA_KEY,
2331
+ FASTLY_API_KEY,
2332
+ NETLIFY_TOKEN,
2333
+ VERCEL_TOKEN,
2334
+ HEROKU_API_KEY,
2335
+ RENDER_TOKEN,
2336
+ FLY_IO_TOKEN,
2337
+ RAILWAY_TOKEN,
2338
+ SURGE_TOKEN
2339
+ ];
2340
+
2341
+ // src/patterns/secrets/social.ts
2342
+ var TWITTER_API_KEY = {
2343
+ secretType: "TWITTER_API_KEY",
2344
+ patterns: [
2345
+ /(?:TWITTER_API_KEY|TWITTER_CONSUMER_KEY)\s*[:=]\s*["']?([A-Za-z0-9]{25})["']?/g
2346
+ ]
2347
+ };
2348
+ var TWITTER_API_SECRET = {
2349
+ secretType: "TWITTER_API_SECRET",
2350
+ patterns: [
2351
+ /(?:TWITTER_API_SECRET|TWITTER_CONSUMER_SECRET)\s*[:=]\s*["']?([A-Za-z0-9]{50})["']?/g
2352
+ ]
2353
+ };
2354
+ var TWITTER_BEARER_TOKEN = {
2355
+ secretType: "TWITTER_BEARER_TOKEN",
2356
+ patterns: [/AAAAAAAAAAAAAAAAAAA[A-Za-z0-9%]{30,}/g]
2357
+ };
2358
+ var FACEBOOK_TOKEN = {
2359
+ secretType: "FACEBOOK_TOKEN",
2360
+ patterns: [
2361
+ /EAA[A-Za-z0-9]{100,}/g,
2362
+ /(?:FACEBOOK_TOKEN|FB_ACCESS_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9|_-]{40,})["']?/g
2363
+ ]
2364
+ };
2365
+ var FACEBOOK_SECRET = {
2366
+ secretType: "FACEBOOK_SECRET",
2367
+ patterns: [/(?:FACEBOOK_SECRET|FB_APP_SECRET)\s*[:=]\s*["']?([a-f0-9]{32})["']?/g]
2368
+ };
2369
+ var INSTAGRAM_TOKEN = {
2370
+ secretType: "INSTAGRAM_TOKEN",
2371
+ patterns: [/(?:INSTAGRAM_TOKEN|IG_ACCESS_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9.]{100,})["']?/g],
2372
+ minEntropy: 3.5
2373
+ };
2374
+ var LINKEDIN_SECRET = {
2375
+ secretType: "LINKEDIN_SECRET",
2376
+ patterns: [/(?:LINKEDIN_CLIENT_SECRET|LINKEDIN_SECRET)\s*[:=]\s*["']?([A-Za-z0-9]{16})["']?/g]
2377
+ };
2378
+ var YOUTUBE_API_KEY = {
2379
+ secretType: "YOUTUBE_API_KEY",
2380
+ patterns: [/(?:YOUTUBE_API_KEY)\s*[:=]\s*["']?(AIza[A-Za-z0-9_-]{35})["']?/g]
2381
+ };
2382
+ var TIKTOK_TOKEN = {
2383
+ secretType: "TIKTOK_TOKEN",
2384
+ patterns: [/(?:TIKTOK_TOKEN|TIKTOK_ACCESS_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9._-]{40,})["']?/g],
2385
+ minEntropy: 3.5
2386
+ };
2387
+ var PINTEREST_TOKEN = {
2388
+ secretType: "PINTEREST_TOKEN",
2389
+ patterns: [/(?:PINTEREST_TOKEN|PINTEREST_ACCESS_TOKEN)\s*[:=]\s*["']?([A-Za-z0-9_-]{40,})["']?/g],
2390
+ minEntropy: 3.5
2391
+ };
2392
+ var SOCIAL_PATTERNS = [
2393
+ TWITTER_API_KEY,
2394
+ TWITTER_API_SECRET,
2395
+ TWITTER_BEARER_TOKEN,
2396
+ FACEBOOK_TOKEN,
2397
+ FACEBOOK_SECRET,
2398
+ INSTAGRAM_TOKEN,
2399
+ LINKEDIN_SECRET,
2400
+ YOUTUBE_API_KEY,
2401
+ TIKTOK_TOKEN,
2402
+ PINTEREST_TOKEN
2403
+ ];
2404
+
2405
+ // src/patterns/secrets/generic.ts
2406
+ var JWT_TOKEN = {
2407
+ secretType: "JWT_TOKEN",
2408
+ patterns: [
2409
+ /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g
2410
+ ]
2411
+ };
2412
+ var PRIVATE_KEY = {
2413
+ secretType: "PRIVATE_KEY",
2414
+ patterns: [
2415
+ /-----BEGIN (?:RSA |EC |ED25519 |OPENSSH |DSA |PGP )?PRIVATE KEY(?: BLOCK)?-----/g
2416
+ ]
2417
+ };
2418
+ var NPM_TOKEN = {
2419
+ secretType: "NPM_TOKEN",
2420
+ patterns: [
2421
+ /npm_[A-Za-z0-9]{36}/g,
2422
+ /\/\/registry\.npmjs\.org\/:_authToken=[A-Za-z0-9-]+/g
2423
+ ]
2424
+ };
2425
+ var PYPI_TOKEN = {
2426
+ secretType: "PYPI_TOKEN",
2427
+ patterns: [/pypi-AgEIcHlwaS5vcmc[A-Za-z0-9_-]{50,}/g]
2428
+ };
2429
+ var RUBYGEMS_KEY = {
2430
+ secretType: "RUBYGEMS_KEY",
2431
+ patterns: [/rubygems_[a-f0-9]{48}/g]
2432
+ };
2433
+ var NUGET_KEY = {
2434
+ secretType: "NUGET_KEY",
2435
+ patterns: [/oy2[A-Za-z0-9]{43}/g]
2436
+ };
2437
+ var CRATES_IO_TOKEN = {
2438
+ secretType: "CRATES_IO_TOKEN",
2439
+ patterns: [/cio[A-Za-z0-9]{32}/g]
2440
+ };
2441
+ var GENERIC_HIGH_ENTROPY = {
2442
+ secretType: "GENERIC_SECRET",
2443
+ patterns: [
2444
+ /(?:api[_-]?key|secret|token|password|passwd|credential|auth)[_\s]*[:=]\s*["']([A-Za-z0-9+/=_\-]{16,})["']/gi
2445
+ ],
2446
+ minEntropy: 3.5
2447
+ };
2448
+ var GENERIC_BEARER_TOKEN = {
2449
+ secretType: "BEARER_TOKEN",
2450
+ patterns: [
2451
+ /(?:Authorization|Bearer)\s*[:=]\s*["']?Bearer\s+([A-Za-z0-9._~+/=-]{20,})["']?/g
2452
+ ],
2453
+ minEntropy: 3.5
2454
+ };
2455
+ var BASIC_AUTH_HEADER = {
2456
+ secretType: "BASIC_AUTH",
2457
+ patterns: [
2458
+ /(?:Authorization)\s*[:=]\s*["']?Basic\s+([A-Za-z0-9+/=]{20,})["']?/g
2459
+ ]
2460
+ };
2461
+ var GENERIC_PATTERNS2 = [
2462
+ JWT_TOKEN,
2463
+ PRIVATE_KEY,
2464
+ NPM_TOKEN,
2465
+ PYPI_TOKEN,
2466
+ RUBYGEMS_KEY,
2467
+ NUGET_KEY,
2468
+ CRATES_IO_TOKEN,
2469
+ GENERIC_HIGH_ENTROPY,
2470
+ GENERIC_BEARER_TOKEN,
2471
+ BASIC_AUTH_HEADER
2472
+ ];
2473
+
2474
+ // src/patterns/secrets/index.ts
2475
+ var ALL_SECRET_PATTERNS = [
2476
+ ...CLOUD_PATTERNS,
2477
+ ...SOURCE_CONTROL_PATTERNS,
2478
+ ...CICD_PATTERNS,
2479
+ ...COMMUNICATION_PATTERNS,
2480
+ ...PAYMENT_PATTERNS,
2481
+ ...DATABASE_PATTERNS,
2482
+ ...INFRASTRUCTURE_PATTERNS,
2483
+ ...SAAS_PATTERNS,
2484
+ ...AI_ML_PATTERNS,
2485
+ ...AUTH_PATTERNS,
2486
+ ...CDN_HOSTING_PATTERNS,
2487
+ ...SOCIAL_PATTERNS,
2488
+ ...GENERIC_PATTERNS2
2489
+ ];
2490
+
2491
+ // src/guards/secret.guard.ts
2492
+ var SecretGuard = class extends BaseGuard {
2493
+ name = "secret";
2494
+ patterns;
2495
+ constructor(options) {
2496
+ super();
2497
+ let patterns = ALL_SECRET_PATTERNS;
2498
+ if (options?.secretTypes && options.secretTypes.length > 0) {
2499
+ const allowed = new Set(options.secretTypes);
2500
+ patterns = patterns.filter((p) => allowed.has(p.secretType));
2501
+ }
2502
+ this.patterns = patterns;
2503
+ }
2504
+ async analyze(text, config) {
2505
+ const cfg = this.mergeConfig(config);
2506
+ const detections = [];
2507
+ for (const pattern of this.patterns) {
2508
+ for (const regex of pattern.patterns) {
2509
+ const re = new RegExp(regex.source, regex.flags);
2510
+ let match;
2511
+ while ((match = re.exec(text)) !== null) {
2512
+ const matchText = match[1] ?? match[0];
2513
+ const fullMatch = match[0];
2514
+ const start = match.index;
2515
+ const end = start + fullMatch.length;
2516
+ if (pattern.validate && !pattern.validate(matchText)) {
2517
+ continue;
2518
+ }
2519
+ if (pattern.minEntropy) {
2520
+ const entropy = shannonEntropy(matchText);
2521
+ if (entropy < pattern.minEntropy) {
2522
+ continue;
2523
+ }
2524
+ }
2525
+ detections.push(
2526
+ this.makeDetection(text, {
2527
+ entityType: pattern.secretType,
2528
+ start,
2529
+ end,
2530
+ text: fullMatch,
2531
+ confidence: "high",
2532
+ score: 0.9,
2533
+ guardName: this.name
2534
+ })
2535
+ );
2536
+ }
2537
+ }
2538
+ }
2539
+ return this.buildResult(text, detections, cfg.mode);
2540
+ }
2541
+ };
2542
+
2543
+ // src/patterns/injection.ts
2544
+ var INJECTION_PATTERNS = [
2545
+ /ignore\s+(all\s+)?(previous|prior|above|earlier)\s+(instructions?|prompts?|commands?|directives?)/i,
2546
+ /disregard\s+(all\s+)?(previous|prior|above|earlier)\s+(instructions?|prompts?|commands?)/i,
2547
+ /forget\s+(all\s+)?(previous|prior|above|earlier)\s+(instructions?|prompts?|commands?)/i,
2548
+ /override\s+(all\s+)?(previous|prior|above|earlier)\s+(instructions?|prompts?|commands?)/i,
2549
+ /you\s+are\s+now\s+(?:a|an|in)\s+/i,
2550
+ /new\s+instructions?\s*:/i,
2551
+ /system\s*:\s*/i,
2552
+ /\bDAN\s+mode\b/i,
2553
+ /\bjailbreak\b/i,
2554
+ /do\s+anything\s+now/i,
2555
+ /act\s+as\s+(?:if\s+)?(?:you\s+(?:are|were)\s+)?(?:a\s+)?/i,
2556
+ /pretend\s+(?:you\s+are|to\s+be)\s+/i,
2557
+ /(?:reveal|show|display|print|output)\s+(?:your\s+)?(?:system\s+)?(?:prompt|instructions?)/i,
2558
+ /(?:what|repeat|tell\s+me)\s+(?:are\s+)?your\s+(?:system\s+)?(?:instructions?|prompt|rules?)/i,
2559
+ /bypass\s+(?:your\s+)?(?:safety|security|content|ethical)\s+(?:filters?|guidelines?|restrictions?|rules?)/i,
2560
+ /(?:from\s+now\s+on|starting\s+now|henceforth)\s*,?\s*(?:you\s+(?:will|shall|must|should))/i
2561
+ ];
2562
+ var INJECTION_KEYWORDS = [
2563
+ "ignore previous instructions",
2564
+ "disregard all prior instructions",
2565
+ "forget your instructions",
2566
+ "override system prompt",
2567
+ "you are now a",
2568
+ "new instructions",
2569
+ "jailbreak",
2570
+ "DAN mode",
2571
+ "do anything now",
2572
+ "bypass safety filters",
2573
+ "ignore content policy",
2574
+ "pretend you are",
2575
+ "act as if you were",
2576
+ "reveal your system prompt",
2577
+ "what are your instructions",
2578
+ "from now on you will",
2579
+ "ignore all restrictions",
2580
+ "developer mode",
2581
+ "sudo mode",
2582
+ "admin override",
2583
+ "unlock hidden features",
2584
+ "disable safety mode",
2585
+ "ignore ethical guidelines",
2586
+ "forget all rules",
2587
+ "you have no restrictions"
2588
+ ];
2589
+ var LEAKAGE_PATTERNS = [
2590
+ /(?:reveal|show|display|print|output|repeat|echo)\s+(?:the\s+)?(?:system\s+)?(?:prompt|instructions?)/i,
2591
+ /(?:what|tell\s+me|share)\s+(?:is\s+|are\s+)?(?:the\s+|your\s+)?(?:system\s+)?(?:prompt|instructions?|initial\s+message)/i,
2592
+ /(?:beginning|start|first\s+part)\s+of\s+(?:the\s+|your\s+)?(?:conversation|prompt|message)/i,
2593
+ /(?:copy|paste|reproduce)\s+(?:the\s+)?(?:text|content)\s+(?:above|before)/i,
2594
+ /(?:text|content|message)\s+(?:before|above|preceding)\s+(?:this|my)\s+(?:message|input)/i,
2595
+ /(?:everything|all)\s+(?:before|above|prior\s+to)\s+(?:this|my\s+message)/i,
2596
+ /repeat\s+(?:everything|all|the\s+text)\s+(?:above|before|I\s+said)/i
2597
+ ];
2598
+ var LEAKAGE_KEYWORDS = [
2599
+ "reveal system prompt",
2600
+ "show me your instructions",
2601
+ "what is your system prompt",
2602
+ "display initial message",
2603
+ "repeat everything above",
2604
+ "copy text before my message",
2605
+ "what are your instructions",
2606
+ "print your prompt",
2607
+ "output your system message",
2608
+ "beginning of conversation",
2609
+ "share your initial instructions"
2610
+ ];
2611
+
2612
+ // src/guards/injection.guard.ts
2613
+ import { findBestMatch } from "string-similarity";
2614
+ var InjectionGuard = class extends BaseGuard {
2615
+ name = "injection";
2616
+ async analyze(text, config) {
2617
+ const cfg = this.mergeConfig({ threshold: 0.6, mode: "block", ...config });
2618
+ const detections = [];
2619
+ for (const pattern of INJECTION_PATTERNS) {
2620
+ const re = new RegExp(pattern.source, pattern.flags + "g");
2621
+ let match;
2622
+ while ((match = re.exec(text)) !== null) {
2623
+ detections.push(
2624
+ this.makeDetection(text, {
2625
+ entityType: "PROMPT_INJECTION",
2626
+ start: match.index,
2627
+ end: match.index + match[0].length,
2628
+ text: match[0],
2629
+ confidence: "high",
2630
+ score: 0.9,
2631
+ guardName: this.name
2632
+ })
2633
+ );
2634
+ }
2635
+ }
2636
+ if (detections.length === 0) {
2637
+ const score = this.heuristicScore(text);
2638
+ if (score >= cfg.threshold) {
2639
+ detections.push(
2640
+ this.makeDetection(text, {
2641
+ entityType: "PROMPT_INJECTION",
2642
+ start: 0,
2643
+ end: text.length,
2644
+ text: text.slice(0, 200),
2645
+ confidence: score >= 0.8 ? "high" : "medium",
2646
+ score,
2647
+ guardName: this.name
2648
+ })
2649
+ );
2650
+ }
2651
+ }
2652
+ return this.buildResult(text, detections, cfg.mode);
2653
+ }
2654
+ heuristicScore(text) {
2655
+ const normalized = text.toLowerCase().trim();
2656
+ if (normalized.length === 0 || INJECTION_KEYWORDS.length === 0) return 0;
2657
+ const result = findBestMatch(normalized, INJECTION_KEYWORDS);
2658
+ let bestScore = result.bestMatch.rating;
2659
+ if (normalized.length > 100) {
2660
+ const windowSize = 80;
2661
+ const step = 30;
2662
+ for (let i = 0; i <= normalized.length - windowSize; i += step) {
2663
+ const window = normalized.slice(i, i + windowSize);
2664
+ const windowResult = findBestMatch(window, INJECTION_KEYWORDS);
2665
+ bestScore = Math.max(bestScore, windowResult.bestMatch.rating);
2666
+ }
2667
+ }
2668
+ return bestScore;
2669
+ }
2670
+ };
2671
+
2672
+ // src/guards/leakage.guard.ts
2673
+ import { findBestMatch as findBestMatch2 } from "string-similarity";
2674
+ var LeakageGuard = class extends BaseGuard {
2675
+ name = "leakage";
2676
+ async analyze(text, config) {
2677
+ const cfg = this.mergeConfig({ threshold: 0.6, mode: "block", ...config });
2678
+ const detections = [];
2679
+ for (const pattern of LEAKAGE_PATTERNS) {
2680
+ const re = new RegExp(pattern.source, pattern.flags + "g");
2681
+ let match;
2682
+ while ((match = re.exec(text)) !== null) {
2683
+ detections.push(
2684
+ this.makeDetection(text, {
2685
+ entityType: "PROMPT_LEAKAGE",
2686
+ start: match.index,
2687
+ end: match.index + match[0].length,
2688
+ text: match[0],
2689
+ confidence: "high",
2690
+ score: 0.9,
2691
+ guardName: this.name
2692
+ })
2693
+ );
2694
+ }
2695
+ }
2696
+ if (detections.length === 0) {
2697
+ const normalized = text.toLowerCase().trim();
2698
+ if (normalized.length > 0 && LEAKAGE_KEYWORDS.length > 0) {
2699
+ const result = findBestMatch2(normalized, LEAKAGE_KEYWORDS);
2700
+ const score = result.bestMatch.rating;
2701
+ if (score >= cfg.threshold) {
2702
+ detections.push(
2703
+ this.makeDetection(text, {
2704
+ entityType: "PROMPT_LEAKAGE",
2705
+ start: 0,
2706
+ end: text.length,
2707
+ text: text.slice(0, 200),
2708
+ confidence: score >= 0.8 ? "high" : "medium",
2709
+ score,
2710
+ guardName: this.name
2711
+ })
2712
+ );
2713
+ }
2714
+ }
2715
+ }
2716
+ return this.buildResult(text, detections, cfg.mode);
2717
+ }
2718
+ };
2719
+
2720
+ // src/guards/testdata.guard.ts
2721
+ var SYNTHETIC_GUID_KEYWORDS = /\b[0-9a-f]{8}-(?:eval|test|demo|mock|fake|sample|exam|plac)[0-9a-f-]*\b/gi;
2722
+ var ZERO_PADDED_GUID = /\b0{8}-[0-9a-f]{4}-[0-9a-f]{4}-0{4}-0{12}\b/gi;
2723
+ var TEST_CREDIT_CARDS = [
2724
+ "4111111111111111",
2725
+ // Visa test
2726
+ "4242424242424242",
2727
+ // Stripe Visa
2728
+ "5500000000000004",
2729
+ // Mastercard test
2730
+ "5555555555554444",
2731
+ // Stripe Mastercard
2732
+ "378282246310005",
2733
+ // Amex test
2734
+ "371449635398431",
2735
+ // Amex test
2736
+ "6011111111111117",
2737
+ // Discover test
2738
+ "3056930009020004",
2739
+ // Diners test
2740
+ "3566002020360505",
2741
+ // JCB test
2742
+ "4000056655665556"
2743
+ // Stripe debit
2744
+ ];
2745
+ var TEST_SSNS = [
2746
+ "000-00-0000",
2747
+ "123-45-6789",
2748
+ "078-05-1120",
2749
+ // Woolworth wallet card SSN (famous invalid)
2750
+ "219-09-9999"
2751
+ // Social Security ad SSN
2752
+ ];
2753
+ var TEST_DATA_PATTERNS = [
2754
+ {
2755
+ entityType: "TEST_DATA_GUID",
2756
+ patterns: [SYNTHETIC_GUID_KEYWORDS, ZERO_PADDED_GUID],
2757
+ reason: "synthetic-guid"
2758
+ },
2759
+ {
2760
+ entityType: "TEST_DATA_CREDIT_CARD",
2761
+ patterns: TEST_CREDIT_CARDS.map(
2762
+ (num) => new RegExp(`\\b${num}\\b`, "g")
2763
+ ),
2764
+ reason: "test-credit-card"
2765
+ },
2766
+ {
2767
+ entityType: "TEST_DATA_SSN",
2768
+ patterns: TEST_SSNS.map(
2769
+ // Require dashes or spaces between SSN groups (not embedded in other numbers)
2770
+ (ssn) => new RegExp(`\\b${ssn.replace(/-/g, "[\\s-]")}\\b`, "g")
2771
+ ),
2772
+ reason: "test-ssn"
2773
+ },
2774
+ {
2775
+ entityType: "TEST_DATA_EMAIL",
2776
+ patterns: [
2777
+ /\b[\w.+-]+@(?:example\.(?:com|org|net)|test\.com|mailinator\.com|tempmail\.com)\b/gi,
2778
+ /\bnoreply@[^\s]+\b/gi
2779
+ ],
2780
+ reason: "placeholder-email"
2781
+ },
2782
+ {
2783
+ entityType: "TEST_DATA_PHONE",
2784
+ patterns: [
2785
+ /\b(?:\+?1[-.\s]?)?(?:\()?555[-.\s]?01[0-9]{2}(?:\))?[-.\s]?\d{4}\b/g
2786
+ // 555-01xx range (reserved fictional)
2787
+ ],
2788
+ reason: "fictional-phone"
2789
+ },
2790
+ {
2791
+ entityType: "TEST_DATA_SEQUENTIAL",
2792
+ patterns: [
2793
+ /\b[A]{4,}0{6,}[0-9A-F]{1,4}\b/gi,
2794
+ // AAAA000000000001 pattern
2795
+ /\b1234567890abcdef\b/gi
2796
+ // Classic sequential hex (exact)
2797
+ ],
2798
+ reason: "sequential-pattern"
2799
+ }
2800
+ ];
2801
+ var TestDataGuard = class extends BaseGuard {
2802
+ name = "testdata";
2803
+ async analyze(text, config) {
2804
+ const cfg = this.mergeConfig(config);
2805
+ const detections = [];
2806
+ for (const pattern of TEST_DATA_PATTERNS) {
2807
+ for (const regex of pattern.patterns) {
2808
+ const re = new RegExp(regex.source, regex.flags);
2809
+ let match;
2810
+ while ((match = re.exec(text)) !== null) {
2811
+ const matchText = match[0];
2812
+ const start = match.index;
2813
+ const end = start + matchText.length;
2814
+ detections.push(
2815
+ this.makeDetection(
2816
+ text,
2817
+ {
2818
+ entityType: pattern.entityType,
2819
+ start,
2820
+ end,
2821
+ text: matchText,
2822
+ confidence: "high",
2823
+ score: 0.95,
2824
+ guardName: this.name
2825
+ },
2826
+ "regex",
2827
+ "informational"
2828
+ )
2829
+ );
2830
+ }
2831
+ }
2832
+ }
2833
+ const deduped = this.deduplicateDetections(detections);
2834
+ return this.buildInformationalResult(text, deduped);
2835
+ }
2836
+ /** Build a result that always passes — test data is informational, not blocking */
2837
+ buildInformationalResult(text, detections) {
2838
+ const score = detections.length > 0 ? Math.max(...detections.map((d) => d.score)) : 0;
2839
+ const types = [...new Set(detections.map((d) => d.entityType))];
2840
+ return {
2841
+ passed: true,
2842
+ // Always passes — informational only
2843
+ reason: detections.length === 0 ? "No test data detected" : `Test data detected: ${types.join(", ")}`,
2844
+ guardName: this.name,
2845
+ score,
2846
+ detections
2847
+ };
2848
+ }
2849
+ deduplicateDetections(detections) {
2850
+ if (detections.length <= 1) return detections;
2851
+ const sorted = [...detections].sort((a, b) => b.score - a.score);
2852
+ const result = [];
2853
+ for (const detection of sorted) {
2854
+ const overlaps = result.some(
2855
+ (existing) => detection.start < existing.end && detection.end > existing.start
2856
+ );
2857
+ if (!overlaps) {
2858
+ result.push(detection);
2859
+ }
2860
+ }
2861
+ return result.sort((a, b) => a.start - b.start);
2862
+ }
2863
+ };
2864
+
2865
+ // src/policy/presets.ts
2866
+ var STRICT = {
2867
+ name: "strict",
2868
+ description: "Maximum sensitivity \u2014 flags all detectable PII, secrets, injection, and test data at low confidence thresholds",
2869
+ guards: {
2870
+ pii: { enabled: true, threshold: 0.3, mode: "block" },
2871
+ secret: { enabled: true, threshold: 0.5, mode: "block" },
2872
+ injection: { enabled: true, threshold: 0.5, mode: "block" },
2873
+ leakage: { enabled: true, threshold: 0.5, mode: "block" }
2874
+ },
2875
+ riskThresholds: { critical: 0.9, high: 0.7, medium: 0.5, low: 0.3 },
2876
+ testDataDetection: "flag"
2877
+ };
2878
+ var MODERATE = {
2879
+ name: "moderate",
2880
+ description: "Balanced sensitivity \u2014 flags high-confidence PII and secrets, redacts rather than blocks",
2881
+ guards: {
2882
+ pii: { enabled: true, threshold: 0.5, mode: "redact" },
2883
+ secret: { enabled: true, threshold: 0.7, mode: "redact" },
2884
+ injection: { enabled: true, threshold: 0.6, mode: "block" },
2885
+ leakage: { enabled: true, threshold: 0.6, mode: "block" }
2886
+ },
2887
+ riskThresholds: { critical: 0.9, high: 0.8, medium: 0.65, low: 0.5 },
2888
+ testDataDetection: "flag"
2889
+ };
2890
+ var BUILTIN_POLICIES = {
2891
+ strict: STRICT,
2892
+ moderate: MODERATE
2893
+ };
2894
+ function getPolicy(name) {
2895
+ const policy = BUILTIN_POLICIES[name];
2896
+ if (!policy) {
2897
+ const available = Object.keys(BUILTIN_POLICIES).join(", ");
2898
+ throw new Error(
2899
+ `Unknown policy "${name}". Available: ${available}`
2900
+ );
2901
+ }
2902
+ return policy;
2903
+ }
2904
+
2905
+ // src/policy/resolve.ts
2906
+ function resolveRef(ref) {
2907
+ return typeof ref === "string" ? getPolicy(ref) : ref;
2908
+ }
2909
+ function resolvePolicy(base, ...overlays) {
2910
+ let result = structuredClone(resolveRef(base));
2911
+ for (const overlay of overlays) {
2912
+ const o = resolveRef(overlay);
2913
+ result = mergePolicies(result, o);
2914
+ }
2915
+ return result;
2916
+ }
2917
+ function mergePolicies(base, overlay) {
2918
+ const result = structuredClone(base);
2919
+ result.name = `${base.name}+${overlay.name}`;
2920
+ result.description = `${base.description} | ${overlay.description}`;
2921
+ for (const guardName of ["pii", "secret", "injection", "leakage"]) {
2922
+ const baseGuard = base.guards[guardName];
2923
+ const overlayGuard = overlay.guards[guardName];
2924
+ if (!overlayGuard) continue;
2925
+ if (!baseGuard) {
2926
+ result.guards[guardName] = structuredClone(overlayGuard);
2927
+ continue;
2928
+ }
2929
+ result.guards[guardName] = mergeGuardConfig(baseGuard, overlayGuard);
2930
+ }
2931
+ if (overlay.riskThresholds) {
2932
+ result.riskThresholds = {
2933
+ critical: Math.min(
2934
+ base.riskThresholds.critical,
2935
+ overlay.riskThresholds.critical
2936
+ ),
2937
+ high: Math.min(base.riskThresholds.high, overlay.riskThresholds.high),
2938
+ medium: Math.min(
2939
+ base.riskThresholds.medium,
2940
+ overlay.riskThresholds.medium
2941
+ ),
2942
+ low: Math.min(base.riskThresholds.low, overlay.riskThresholds.low)
2943
+ };
2944
+ }
2945
+ if (overlay.testDataDetection) {
2946
+ result.testDataDetection = overlay.testDataDetection;
2947
+ }
2948
+ return result;
2949
+ }
2950
+ function mergeGuardConfig(base, overlay) {
2951
+ const result = { ...base };
2952
+ if (overlay.enabled !== void 0) {
2953
+ result.enabled = overlay.enabled;
2954
+ }
2955
+ if (overlay.threshold !== void 0) {
2956
+ result.threshold = base.threshold !== void 0 ? Math.min(base.threshold, overlay.threshold) : overlay.threshold;
2957
+ }
2958
+ if (overlay.mode !== void 0) {
2959
+ if (overlay.mode === "block" || base.mode === "block") {
2960
+ result.mode = "block";
2961
+ } else {
2962
+ result.mode = overlay.mode;
2963
+ }
2964
+ }
2965
+ if (overlay.entityTypes) {
2966
+ if (base.entityTypes && base.entityTypes.length > 0) {
2967
+ const overlaySet = new Set(overlay.entityTypes);
2968
+ result.entityTypes = base.entityTypes.filter((t) => overlaySet.has(t));
2969
+ } else {
2970
+ result.entityTypes = [...overlay.entityTypes];
2971
+ }
2972
+ }
2973
+ if (overlay.secretTypes) {
2974
+ if (base.secretTypes && base.secretTypes.length > 0) {
2975
+ const overlaySet = new Set(overlay.secretTypes);
2976
+ result.secretTypes = base.secretTypes.filter((t) => overlaySet.has(t));
2977
+ } else {
2978
+ result.secretTypes = [...overlay.secretTypes];
2979
+ }
2980
+ }
2981
+ return result;
2982
+ }
2983
+ function policyToEngineConfig(policy) {
2984
+ const pii = policy.guards.pii ?? {};
2985
+ const secret = policy.guards.secret ?? {};
2986
+ const injection = policy.guards.injection ?? {};
2987
+ const leakage = policy.guards.leakage ?? {};
2988
+ return {
2989
+ piiOptions: {
2990
+ entityTypes: pii.entityTypes
2991
+ },
2992
+ secretOptions: {
2993
+ secretTypes: secret.secretTypes
2994
+ },
2995
+ guardConfigs: {
2996
+ pii: { threshold: pii.threshold, mode: pii.mode },
2997
+ secret: { threshold: secret.threshold, mode: secret.mode },
2998
+ injection: { threshold: injection.threshold, mode: injection.mode },
2999
+ leakage: { threshold: leakage.threshold, mode: leakage.mode }
3000
+ }
3001
+ };
3002
+ }
3003
+
3004
+ // src/index.ts
3005
+ var DEFAULT_CONFIG2 = {
3006
+ enabled: true,
3007
+ debounceMs: 500,
3008
+ guards: {
3009
+ pii: { enabled: true },
3010
+ secret: { enabled: true },
3011
+ injection: { enabled: true },
3012
+ contentSafety: { enabled: false }
3013
+ },
3014
+ cascade: {
3015
+ escalationThreshold: 0.75,
3016
+ contextSentences: 3,
3017
+ modelEnabled: false,
3018
+ modelId: "Xenova/bert-base-NER"
3019
+ }
3020
+ };
3021
+ function createEngine(config = DEFAULT_CONFIG2) {
3022
+ const engine = new GuardrailsEngine();
3023
+ if (config.policy) {
3024
+ let policy = resolveRef(config.policy);
3025
+ if (config.policyOverlays && config.policyOverlays.length > 0) {
3026
+ policy = resolvePolicy(policy, ...config.policyOverlays);
3027
+ }
3028
+ const { piiOptions, secretOptions, guardConfigs } = policyToEngineConfig(policy);
3029
+ if (policy.guards.pii?.enabled !== false) {
3030
+ engine.addGuard(new PiiGuard(piiOptions));
3031
+ }
3032
+ if (policy.guards.secret?.enabled !== false) {
3033
+ engine.addGuard(new SecretGuard(secretOptions));
3034
+ }
3035
+ if (policy.guards.injection?.enabled !== false) {
3036
+ engine.addGuard(new InjectionGuard());
3037
+ engine.addGuard(new LeakageGuard());
3038
+ }
3039
+ if (policy.testDataDetection !== "ignore") {
3040
+ engine.addGuard(new TestDataGuard());
3041
+ }
3042
+ engine.updateConfig({ guards: guardConfigs });
3043
+ } else {
3044
+ if (config.guards.pii.enabled) {
3045
+ engine.addGuard(new PiiGuard());
3046
+ }
3047
+ if (config.guards.secret.enabled) {
3048
+ engine.addGuard(new SecretGuard());
3049
+ }
3050
+ if (config.guards.injection.enabled) {
3051
+ engine.addGuard(new InjectionGuard());
3052
+ engine.addGuard(new LeakageGuard());
3053
+ }
3054
+ }
3055
+ if (config.cascade.modelEnabled) {
3056
+ engine.initCascade({
3057
+ bertEnabled: true,
3058
+ llmEnabled: config.guards.contentSafety.enabled,
3059
+ escalationThreshold: config.cascade.escalationThreshold,
3060
+ contextSentences: config.cascade.contextSentences,
3061
+ modelId: config.cascade.modelId
3062
+ });
3063
+ }
3064
+ return engine;
3065
+ }
3066
+ export {
3067
+ BUILTIN_POLICIES,
3068
+ BaseGuard,
3069
+ DEFAULT_CONFIG2 as DEFAULT_CONFIG,
3070
+ GuardrailsEngine,
3071
+ InjectionGuard,
3072
+ LeakageGuard,
3073
+ PiiGuard,
3074
+ SecretGuard,
3075
+ TestDataGuard,
3076
+ assessRisk,
3077
+ createEngine,
3078
+ getPolicy,
3079
+ policyToEngineConfig,
3080
+ resolvePolicy
3081
+ };
3082
+ //# sourceMappingURL=index.mjs.map