@privacyscrubber/sdk 2.4.1 → 2.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/browser.js +84 -29
- package/cli.js +71 -27
- package/examples/python-bridge/bridge_daemon.cjs +24 -5
- package/examples/python-bridge/fastapi_example.py +1 -1
- package/examples/python-bridge/privacyscrubber/__init__.py +1 -1
- package/examples/python-bridge/privacyscrubber/bridge_daemon.cjs +24 -5
- package/examples/python-bridge/privacyscrubber/cli.py +1 -1
- package/examples/python-bridge/privacyscrubber/client.py +12 -0
- package/examples/python-bridge/privacyscrubber/langchain.py +31 -7
- package/examples/python-bridge/pyproject.toml +1 -1
- package/examples/python-bridge/setup.py +1 -1
- package/examples/python-bridge/test_python_bridge.py +1 -1
- package/fastmcp.cjs +45 -9
- package/index.cjs +67 -18
- package/index.d.ts +3 -2
- package/index.js +67 -18
- package/package.json +12 -1
- package/polyfill.js +31 -13
- package/ps-license-manager.js +1 -1
- package/ps-pii-engine.cjs +1 -1
- package/sarif.cjs +388 -0
- package/sarif.js +37 -0
- package/scrubber-core.cjs +1 -1
- package/vercel-ai.cjs +52 -6
- package/vision.cjs +15 -11
- package/vision.js +15 -11
package/sarif.cjs
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
2
|
+
// cli/sarif.js
|
|
3
|
+
// SARIF 2.1.0 emitter for PrivacyScrubber CLI & CI/CD Pipelines
|
|
4
|
+
// • Zero Raw PII Egress — only normalized types, rules, and fingerprints
|
|
5
|
+
// • Fully compatible with GitHub Code Scanning, GitLab Code Quality, Azure DevOps
|
|
6
|
+
// • Zero external dependencies — pure Node.js built-ins (crypto, fs, path)
|
|
7
|
+
// • endLine / endColumn accurately calculated from match position & length
|
|
8
|
+
// • tool.driver.rules mapped from ZTDS compliance levels
|
|
9
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const crypto = require('crypto');
|
|
16
|
+
|
|
17
|
+
// ─── PII Entity Type → SARIF Level Mapping ──────────────────────────────
|
|
18
|
+
const PII_LEVEL_MAP = {
|
|
19
|
+
passport: 'error',
|
|
20
|
+
ssn: 'error',
|
|
21
|
+
iban: 'error',
|
|
22
|
+
credit_card: 'error',
|
|
23
|
+
medical_id: 'error',
|
|
24
|
+
tax_id: 'error',
|
|
25
|
+
driver_license: 'error',
|
|
26
|
+
biometric: 'error',
|
|
27
|
+
secret: 'error',
|
|
28
|
+
api_key: 'error',
|
|
29
|
+
private_key: 'error',
|
|
30
|
+
id: 'error',
|
|
31
|
+
email: 'warning',
|
|
32
|
+
phone: 'warning',
|
|
33
|
+
address: 'warning',
|
|
34
|
+
date_of_birth: 'warning',
|
|
35
|
+
ip: 'warning',
|
|
36
|
+
ip_address: 'warning',
|
|
37
|
+
name: 'note',
|
|
38
|
+
city: 'note',
|
|
39
|
+
postal_code: 'note',
|
|
40
|
+
custom: 'warning'
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const PII_PLACEHOLDER = {
|
|
44
|
+
passport: '[REDACTED:PASSPORT]',
|
|
45
|
+
ssn: '[REDACTED:SSN]',
|
|
46
|
+
iban: '[REDACTED:IBAN]',
|
|
47
|
+
credit_card: '[REDACTED:CARD]',
|
|
48
|
+
medical_id: '[REDACTED:MEDICAL_ID]',
|
|
49
|
+
tax_id: '[REDACTED:TAX_ID]',
|
|
50
|
+
driver_license: '[REDACTED:LICENSE]',
|
|
51
|
+
biometric: '[REDACTED:BIOMETRIC]',
|
|
52
|
+
secret: '[REDACTED:SECRET]',
|
|
53
|
+
api_key: '[REDACTED:API_KEY]',
|
|
54
|
+
private_key: '[REDACTED:PRIVATE_KEY]',
|
|
55
|
+
id: '[REDACTED:ID]',
|
|
56
|
+
email: '[REDACTED:EMAIL]',
|
|
57
|
+
phone: '[REDACTED:PHONE]',
|
|
58
|
+
address: '[REDACTED:ADDRESS]',
|
|
59
|
+
date_of_birth: '[REDACTED:DOB]',
|
|
60
|
+
ip: '[REDACTED:IP]',
|
|
61
|
+
ip_address: '[REDACTED:IP]',
|
|
62
|
+
name: '[REDACTED:NAME]',
|
|
63
|
+
city: '[REDACTED:CITY]',
|
|
64
|
+
postal_code: '[REDACTED:POSTAL]',
|
|
65
|
+
custom: '[REDACTED:CUSTOM]'
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// ─── Help Documentation URIs ───────────────────────────────────────────
|
|
69
|
+
const RULE_HELP = {
|
|
70
|
+
passport: 'https://privacyscrubber.com/compliance/gdpr',
|
|
71
|
+
ssn: 'https://privacyscrubber.com/compliance/iso27001',
|
|
72
|
+
iban: 'https://privacyscrubber.com/compliance/pci',
|
|
73
|
+
credit_card: 'https://privacyscrubber.com/compliance/pci',
|
|
74
|
+
medical_id: 'https://privacyscrubber.com/compliance/hipaa',
|
|
75
|
+
tax_id: 'https://privacyscrubber.com/compliance/gdpr',
|
|
76
|
+
driver_license: 'https://privacyscrubber.com/compliance/gdpr',
|
|
77
|
+
biometric: 'https://privacyscrubber.com/compliance/eu-ai-act',
|
|
78
|
+
secret: 'https://privacyscrubber.com/solutions/dev',
|
|
79
|
+
api_key: 'https://privacyscrubber.com/solutions/dev',
|
|
80
|
+
private_key: 'https://privacyscrubber.com/solutions/dev',
|
|
81
|
+
id: 'https://privacyscrubber.com/compliance/gdpr',
|
|
82
|
+
email: 'https://privacyscrubber.com/compliance/gdpr',
|
|
83
|
+
phone: 'https://privacyscrubber.com/compliance/gdpr',
|
|
84
|
+
address: 'https://privacyscrubber.com/compliance/gdpr',
|
|
85
|
+
date_of_birth: 'https://privacyscrubber.com/compliance/gdpr',
|
|
86
|
+
ip: 'https://privacyscrubber.com/compliance/iso27001',
|
|
87
|
+
ip_address: 'https://privacyscrubber.com/compliance/iso27001',
|
|
88
|
+
name: 'https://privacyscrubber.com/compliance/gdpr',
|
|
89
|
+
city: 'https://privacyscrubber.com/compliance/gdpr',
|
|
90
|
+
postal_code: 'https://privacyscrubber.com/compliance/gdpr',
|
|
91
|
+
custom: 'https://privacyscrubber.com/sdk'
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
function normalizePiiType(type) {
|
|
95
|
+
if (!type) return 'custom';
|
|
96
|
+
const clean = String(type).trim().toLowerCase().replace(/[^a-z0-9_]/g, '_');
|
|
97
|
+
return clean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ─── Deterministic Fingerprint (GitHub Code Scanning deduplication) ────
|
|
101
|
+
function generateFingerprint(piiType, uri, position, length) {
|
|
102
|
+
const normType = normalizePiiType(piiType);
|
|
103
|
+
const line = position?.line || 1;
|
|
104
|
+
const col = position?.column || 1;
|
|
105
|
+
const targetUri = uri || 'stdin';
|
|
106
|
+
const material = `${normType}|${targetUri}|${line}:${col}|${length}`;
|
|
107
|
+
const hash = crypto.createHash('sha256').update(material).digest('hex');
|
|
108
|
+
return {
|
|
109
|
+
primary: `${normType}-${hash.substring(0, 16)}`,
|
|
110
|
+
full: `sha256:${hash}`
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ─── Generate tool.driver.rules from PII_LEVEL_MAP ─────────────────────
|
|
115
|
+
function generateRules() {
|
|
116
|
+
const rules = [];
|
|
117
|
+
for (const [piiType, level] of Object.entries(PII_LEVEL_MAP)) {
|
|
118
|
+
const ruleId = `PS-${piiType.toUpperCase()}`;
|
|
119
|
+
const securitySeverity = level === 'error' ? '9.0' :
|
|
120
|
+
level === 'warning' ? '6.0' : '3.0';
|
|
121
|
+
|
|
122
|
+
rules.push({
|
|
123
|
+
id: ruleId,
|
|
124
|
+
name: `PrivacyScrubber_${piiType.toUpperCase()}_Rule`,
|
|
125
|
+
shortDescription: {
|
|
126
|
+
text: `Identifies ${piiType.toUpperCase()} patterns subject to ZTDS zero-egress sanitization`
|
|
127
|
+
},
|
|
128
|
+
fullDescription: {
|
|
129
|
+
text: `PrivacyScrubber rule detecting ${piiType.toUpperCase()} in source code, prompts, configs, ` +
|
|
130
|
+
`logs, or vector embeddings. Enforces ZTDS in-memory tokenization before network egress.`
|
|
131
|
+
},
|
|
132
|
+
helpUri: RULE_HELP[piiType] || 'https://privacyscrubber.com',
|
|
133
|
+
properties: {
|
|
134
|
+
tags: ['privacy', 'pii', 'compliance', 'ztds', piiType],
|
|
135
|
+
precision: 'very-high',
|
|
136
|
+
'problem.severity': level,
|
|
137
|
+
'security-severity': securitySeverity
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return rules;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ─── Transform Raw Engine Finding → SARIF 2.1.0 Result ─────────────────
|
|
145
|
+
function findingToSarifResult(finding) {
|
|
146
|
+
const normType = normalizePiiType(finding.pii_type || finding.type);
|
|
147
|
+
const level = PII_LEVEL_MAP[normType] || 'note';
|
|
148
|
+
const placeholder = PII_PLACEHOLDER[normType] || `[REDACTED:${normType.toUpperCase()}]`;
|
|
149
|
+
const ruleId = `PS-${normType.toUpperCase()}`;
|
|
150
|
+
|
|
151
|
+
const pos = finding.position || {
|
|
152
|
+
line: finding.line || 1,
|
|
153
|
+
column: finding.column || 1
|
|
154
|
+
};
|
|
155
|
+
const length = Number(finding.match_length || finding.length || (finding.value ? finding.value.length : 0)) || 1;
|
|
156
|
+
const fileUri = finding.file_uri || finding.file || 'input.txt';
|
|
157
|
+
|
|
158
|
+
const endLine = finding.end_position?.line || finding.endLine || pos.line;
|
|
159
|
+
const endColumn = finding.end_position?.column || finding.endColumn || (pos.column + length);
|
|
160
|
+
const fingerprint = generateFingerprint(normType, fileUri, pos, length);
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
ruleId,
|
|
164
|
+
level,
|
|
165
|
+
message: {
|
|
166
|
+
text: `PrivacyScrubber detected sensitive ${normType.toUpperCase()} token (${placeholder}) ` +
|
|
167
|
+
`at line ${pos.line}, column ${pos.column}. Sanitized locally in RAM (Zero Egress).`
|
|
168
|
+
},
|
|
169
|
+
locations: [{
|
|
170
|
+
physicalLocation: {
|
|
171
|
+
artifactLocation: {
|
|
172
|
+
uri: fileUri,
|
|
173
|
+
uriBaseId: '%SRCROOT%'
|
|
174
|
+
},
|
|
175
|
+
region: {
|
|
176
|
+
startLine: pos.line,
|
|
177
|
+
startColumn: pos.column,
|
|
178
|
+
endLine: endLine,
|
|
179
|
+
endColumn: endColumn,
|
|
180
|
+
snippet: {
|
|
181
|
+
text: finding.context_snippet || placeholder
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}],
|
|
186
|
+
fingerprints: {
|
|
187
|
+
primaryFingerprint: fingerprint.primary,
|
|
188
|
+
sha256: fingerprint.full
|
|
189
|
+
},
|
|
190
|
+
properties: {
|
|
191
|
+
piiType: normType,
|
|
192
|
+
matchLength: length,
|
|
193
|
+
detector: finding.detector || 'ztds-pii-engine',
|
|
194
|
+
zeroEgress: true
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ─── Convert character offset in text to line and column ───────────────
|
|
200
|
+
function offsetToLineColumn(text, offset) {
|
|
201
|
+
let line = 1;
|
|
202
|
+
let column = 1;
|
|
203
|
+
const max = Math.min(offset, text.length);
|
|
204
|
+
for (let i = 0; i < max; i++) {
|
|
205
|
+
if (text[i] === '\n') {
|
|
206
|
+
line++;
|
|
207
|
+
column = 1;
|
|
208
|
+
} else {
|
|
209
|
+
column++;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return { line, column };
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ─── Adapt sanitize() engine matches to SARIF findings ─────────────────
|
|
216
|
+
function sanitizeResultToFindings(sanitizeResult, sourceText = '', fileUri = 'input.txt') {
|
|
217
|
+
const matches = sanitizeResult.matches || sanitizeResult.spans || [];
|
|
218
|
+
return matches.map(m => {
|
|
219
|
+
const pos = offsetToLineColumn(sourceText, m.start);
|
|
220
|
+
const length = (m.end - m.start) || (m.value ? m.value.length : 1);
|
|
221
|
+
const endPos = typeof m.end === 'number' ? offsetToLineColumn(sourceText, m.end) : null;
|
|
222
|
+
const normType = normalizePiiType(m.type);
|
|
223
|
+
const placeholder = PII_PLACEHOLDER[normType] || m.token || '[REDACTED]';
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
pii_type: normType,
|
|
227
|
+
file_uri: fileUri,
|
|
228
|
+
position: pos,
|
|
229
|
+
end_position: endPos,
|
|
230
|
+
match_length: length,
|
|
231
|
+
context_snippet: placeholder,
|
|
232
|
+
detector: 'ztds-ram-engine'
|
|
233
|
+
};
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ─── Main SARIF 2.1.0 Emitter ──────────────────────────────────────────
|
|
238
|
+
function emitSarif(findings, options = {}) {
|
|
239
|
+
const {
|
|
240
|
+
toolName = 'PrivacyScrubber',
|
|
241
|
+
toolVersion = '2.4.3',
|
|
242
|
+
sarifVersion = '2.1.0',
|
|
243
|
+
repositoryUri = '',
|
|
244
|
+
commitSha = '',
|
|
245
|
+
pretty = false
|
|
246
|
+
} = options;
|
|
247
|
+
|
|
248
|
+
const results = Array.isArray(findings) ? findings.map(findingToSarifResult) : [];
|
|
249
|
+
|
|
250
|
+
const sarifLog = {
|
|
251
|
+
$schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Documents/Comprehensive%20SARIF%20JSON%20Schema/sarif-schema-2.1.0.json',
|
|
252
|
+
version: sarifVersion,
|
|
253
|
+
runs: [{
|
|
254
|
+
tool: {
|
|
255
|
+
driver: {
|
|
256
|
+
name: toolName,
|
|
257
|
+
version: toolVersion,
|
|
258
|
+
informationUri: 'https://privacyscrubber.com',
|
|
259
|
+
rules: generateRules()
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
results,
|
|
263
|
+
columnKind: 'utf16CodeUnits',
|
|
264
|
+
properties: {
|
|
265
|
+
scanTimestamp: new Date().toISOString(),
|
|
266
|
+
repositoryUri: repositoryUri || undefined,
|
|
267
|
+
commitSha: commitSha || undefined,
|
|
268
|
+
ztdsConformant: true,
|
|
269
|
+
zeroNetworkEgress: true
|
|
270
|
+
}
|
|
271
|
+
}]
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
return pretty ? JSON.stringify(sarifLog, null, 2) : JSON.stringify(sarifLog);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// ─── Zero-Dependency CLI Argument Parser ───────────────────────────────
|
|
278
|
+
function parseArgs(argv) {
|
|
279
|
+
const args = {
|
|
280
|
+
input: '-',
|
|
281
|
+
output: '-',
|
|
282
|
+
pretty: false,
|
|
283
|
+
repo: '',
|
|
284
|
+
commit: '',
|
|
285
|
+
help: false
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
for (let i = 0; i < argv.length; i++) {
|
|
289
|
+
const arg = argv[i];
|
|
290
|
+
if (arg === '-h' || arg === '--help') {
|
|
291
|
+
args.help = true;
|
|
292
|
+
} else if (arg === '-i' || arg === '--input') {
|
|
293
|
+
args.input = argv[++i] || '-';
|
|
294
|
+
} else if (arg === '-o' || arg === '--output') {
|
|
295
|
+
args.output = argv[++i] || '-';
|
|
296
|
+
} else if (arg === '-p' || arg === '--pretty') {
|
|
297
|
+
args.pretty = true;
|
|
298
|
+
} else if (arg === '-r' || arg === '--repo') {
|
|
299
|
+
args.repo = argv[++i] || '';
|
|
300
|
+
} else if (arg === '-c' || arg === '--commit') {
|
|
301
|
+
args.commit = argv[++i] || '';
|
|
302
|
+
} else if (!arg.startsWith('-') && args.input === '-') {
|
|
303
|
+
args.input = arg;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return args;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// ─── CLI Entrypoint ────────────────────────────────────────────────────
|
|
311
|
+
function main() {
|
|
312
|
+
const args = parseArgs(process.argv.slice(2));
|
|
313
|
+
|
|
314
|
+
if (args.help) {
|
|
315
|
+
console.log(`PrivacyScrubber SARIF 2.1.0 Emitter v2.4.3
|
|
316
|
+
Usage: node cli/sarif.js [options] [inputFile]
|
|
317
|
+
|
|
318
|
+
Options:
|
|
319
|
+
-i, --input <file> Input JSON findings file or '-' for stdin (default: -)
|
|
320
|
+
-o, --output <file> Output SARIF file or '-' for stdout (default: -)
|
|
321
|
+
-p, --pretty Format output with indentation
|
|
322
|
+
-r, --repo <url> Source repository URI
|
|
323
|
+
-c, --commit <sha> Commit SHA
|
|
324
|
+
-h, --help Show this help message`);
|
|
325
|
+
process.exit(0);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function processContent(raw) {
|
|
329
|
+
try {
|
|
330
|
+
let findings;
|
|
331
|
+
const parsed = JSON.parse(raw);
|
|
332
|
+
if (Array.isArray(parsed)) {
|
|
333
|
+
findings = parsed;
|
|
334
|
+
} else if (parsed && Array.isArray(parsed.findings)) {
|
|
335
|
+
findings = parsed.findings;
|
|
336
|
+
} else if (parsed && (parsed.matches || parsed.spans)) {
|
|
337
|
+
findings = sanitizeResultToFindings(parsed, parsed.sourceText || '', args.input === '-' ? 'stdin' : args.input);
|
|
338
|
+
} else {
|
|
339
|
+
findings = [];
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const sarif = emitSarif(findings, {
|
|
343
|
+
pretty: args.pretty,
|
|
344
|
+
repositoryUri: args.repo,
|
|
345
|
+
commitSha: args.commit
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
if (args.output === '-') {
|
|
349
|
+
process.stdout.write(sarif + '\n');
|
|
350
|
+
} else {
|
|
351
|
+
fs.writeFileSync(args.output, sarif, 'utf8');
|
|
352
|
+
}
|
|
353
|
+
} catch (err) {
|
|
354
|
+
console.error(`Error processing findings for SARIF output: ${err.message}`);
|
|
355
|
+
process.exit(1);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (args.input === '-') {
|
|
360
|
+
const chunks = [];
|
|
361
|
+
process.stdin.on('data', c => chunks.push(c));
|
|
362
|
+
process.stdin.on('end', () => {
|
|
363
|
+
const raw = Buffer.concat(chunks).toString('utf8');
|
|
364
|
+
processContent(raw || '[]');
|
|
365
|
+
});
|
|
366
|
+
} else {
|
|
367
|
+
if (!fs.existsSync(args.input)) {
|
|
368
|
+
console.error(`Error: Input file does not exist: ${args.input}`);
|
|
369
|
+
process.exit(1);
|
|
370
|
+
}
|
|
371
|
+
const raw = fs.readFileSync(args.input, 'utf8');
|
|
372
|
+
processContent(raw);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
module.exports = {
|
|
377
|
+
emitSarif,
|
|
378
|
+
generateRules,
|
|
379
|
+
findingToSarifResult,
|
|
380
|
+
offsetToLineColumn,
|
|
381
|
+
sanitizeResultToFindings,
|
|
382
|
+
PII_LEVEL_MAP,
|
|
383
|
+
PII_PLACEHOLDER
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
if (require.main === module) {
|
|
387
|
+
main();
|
|
388
|
+
}
|
package/sarif.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
2
|
+
// npm-sdk/sarif.js
|
|
3
|
+
// SARIF 2.1.0 module export for @privacyscrubber/sdk
|
|
4
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
5
|
+
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
emitSarif,
|
|
11
|
+
generateRules,
|
|
12
|
+
findingToSarifResult,
|
|
13
|
+
offsetToLineColumn,
|
|
14
|
+
sanitizeResultToFindings,
|
|
15
|
+
PII_LEVEL_MAP,
|
|
16
|
+
PII_PLACEHOLDER
|
|
17
|
+
} = require('./sarif.cjs');
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
emitSarif,
|
|
21
|
+
generateRules,
|
|
22
|
+
findingToSarifResult,
|
|
23
|
+
offsetToLineColumn,
|
|
24
|
+
sanitizeResultToFindings,
|
|
25
|
+
PII_LEVEL_MAP,
|
|
26
|
+
PII_PLACEHOLDER
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
emitSarif,
|
|
31
|
+
generateRules,
|
|
32
|
+
findingToSarifResult,
|
|
33
|
+
offsetToLineColumn,
|
|
34
|
+
sanitizeResultToFindings,
|
|
35
|
+
PII_LEVEL_MAP,
|
|
36
|
+
PII_PLACEHOLDER
|
|
37
|
+
};
|