logshield-cli 0.3.5 → 0.3.6

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/CHANGELOG.md CHANGED
@@ -1,11 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.3.6
4
+
5
+ ### Fixed
6
+
7
+ - `--summary` output now correctly written to stderr (safe for piping & redirects)
8
+
9
+ ### Improved
10
+
11
+ - CLI documentation clarity
12
+ - Blog and docs structure consistency
13
+ - Shared `styles.css` and `main.js` across site pages
14
+
15
+ ### Notes
16
+
17
+ - No breaking changes
18
+
19
+ ## v0.3.5
20
+
21
+ ### Fixed
22
+
23
+ - Corrected CLI version injection in built CJS output
24
+ - Ensured published npm package reflects actual CLI version
25
+
26
+ ### Improved
27
+
28
+ - Deterministic `--dry-run` report formatting (aligned, CI-safe)
29
+ - Dry-run output now strictly non-contextual and stdout-only
30
+
31
+ ### Notes
32
+
33
+ - No engine or rule behavior changes
34
+ - Pure CLI/build correctness release
35
+
36
+ ---
37
+
3
38
  ## v0.3.4
4
39
 
5
40
  ### Fixed
6
41
 
7
42
  - README CI badge link on npmjs.com
8
43
 
44
+ ---
45
+
9
46
  ## v0.3.3
10
47
 
11
48
  ### Added
@@ -9,9 +9,6 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
9
  var __esm = (fn, res) => function __init() {
10
10
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
11
  };
12
- var __commonJS = (cb, mod) => function __require() {
13
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
14
- };
15
12
  var __export = (target, all) => {
16
13
  for (var name in all)
17
14
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -83,6 +80,42 @@ var init_writeOutput = __esm({
83
80
  }
84
81
  });
85
82
 
83
+ // src/cli/summary.ts
84
+ var summary_exports = {};
85
+ __export(summary_exports, {
86
+ printSummary: () => printSummary
87
+ });
88
+ function printSummary(matches) {
89
+ if (!matches || matches.length === 0) {
90
+ process.stderr.write("logshield: no redactions detected\n");
91
+ return;
92
+ }
93
+ const counter = {};
94
+ for (const m of matches) {
95
+ counter[m.rule] = (counter[m.rule] || 0) + 1;
96
+ }
97
+ const entries = Object.entries(counter).map(([rule, count]) => ({ rule, count })).sort((a, b) => {
98
+ if (b.count !== a.count) return b.count - a.count;
99
+ return a.rule.localeCompare(b.rule);
100
+ });
101
+ const maxLen = Math.max(...entries.map((e) => e.rule.length));
102
+ const total = matches.length;
103
+ const label = total === 1 ? "redaction" : "redactions";
104
+ process.stderr.write(`logshield summary: ${total} ${label}
105
+ `);
106
+ for (const { rule, count } of entries) {
107
+ process.stderr.write(
108
+ ` ${rule.padEnd(maxLen)} x${count}
109
+ `
110
+ );
111
+ }
112
+ }
113
+ var init_summary = __esm({
114
+ "src/cli/summary.ts"() {
115
+ "use strict";
116
+ }
117
+ });
118
+
86
119
  // src/engine/applyRules.ts
87
120
  function applyRules(input, rules, ctx, matches) {
88
121
  let output = input;
@@ -349,144 +382,14 @@ var init_sanitizeLog = __esm({
349
382
  }
350
383
  });
351
384
 
352
- // src/cli/summary.ts
353
- var require_summary = __commonJS({
354
- "src/cli/summary.ts"() {
355
- "use strict";
356
- var { readInput: readInput3 } = (init_readInput(), __toCommonJS(readInput_exports));
357
- var { writeOutput: writeOutput3 } = (init_writeOutput(), __toCommonJS(writeOutput_exports));
358
- var { printSummary: printSummary2 } = require_summary();
359
- var { sanitizeLog: sanitizeLog3 } = (init_sanitizeLog(), __toCommonJS(sanitizeLog_exports));
360
- var rawArgs2 = process.argv.slice(2).map((arg) => arg === "-h" ? "--help" : arg);
361
- function getVersion2() {
362
- return true ? "0.3.5" : "unknown";
363
- }
364
- function printHelp2() {
365
- process.stdout.write(`Usage: logshield scan [file]
366
-
367
- Behavior:
368
- - If a file is provided, LogShield reads from that file
369
- - If input is piped, LogShield reads from STDIN automatically
370
- - --stdin is optional and only needed for explicitness
371
-
372
- Options:
373
- --strict Aggressive redaction
374
- --dry-run Preview redactions without modifying output
375
- --stdin Force read from STDIN
376
- --fail-on-detect Exit with code 1 if any redaction occurs
377
- --json JSON output
378
- --summary Print summary
379
- --version Print version
380
- --help Show help
381
- `);
382
- }
383
- function parseArgs2(args) {
384
- const flags = /* @__PURE__ */ new Set();
385
- const positionals = [];
386
- for (const arg of args) {
387
- if (arg.startsWith("--")) {
388
- flags.add(arg);
389
- } else {
390
- positionals.push(arg);
391
- }
392
- }
393
- return { flags, positionals };
394
- }
395
- function isStdinPiped2() {
396
- return !process.stdin.isTTY;
397
- }
398
- function renderDryRunReport2(matches) {
399
- if (matches.length === 0) {
400
- process.stdout.write("[DRY RUN] No redactions detected.\n");
401
- process.stdout.write("No output was modified.\n");
402
- return;
403
- }
404
- const counts = /* @__PURE__ */ new Map();
405
- for (const m of matches) {
406
- counts.set(m.rule, (counts.get(m.rule) || 0) + 1);
407
- }
408
- process.stdout.write("[DRY RUN] Detected redactions:\n");
409
- const maxLen = Math.max(
410
- ...Array.from(counts.keys()).map((k) => k.length)
411
- );
412
- for (const [rule, count] of counts.entries()) {
413
- process.stdout.write(
414
- ` ${rule.padEnd(maxLen)} x${count}
415
- `
416
- );
417
- }
418
- process.stdout.write("\n");
419
- process.stdout.write("No output was modified.\n");
420
- process.stdout.write("Use without --dry-run to apply.\n");
421
- }
422
- async function main2() {
423
- if (rawArgs2.length === 0 || rawArgs2.includes("--help")) {
424
- printHelp2();
425
- process.exit(0);
426
- }
427
- if (rawArgs2.includes("--version")) {
428
- console.log(`logshield v${getVersion2()}`);
429
- process.exit(0);
430
- }
431
- const { flags, positionals } = parseArgs2(rawArgs2);
432
- const command = positionals[0];
433
- if (command !== "scan") {
434
- process.stdout.write("Unknown command\n");
435
- process.exit(1);
436
- }
437
- const file = positionals[1];
438
- const strict = flags.has("--strict");
439
- const json = flags.has("--json");
440
- const summary = flags.has("--summary");
441
- const stdinFlag = flags.has("--stdin");
442
- const failOnDetect = flags.has("--fail-on-detect");
443
- const dryRun = flags.has("--dry-run");
444
- const stdinAuto = isStdinPiped2();
445
- const useStdin = stdinFlag || stdinAuto;
446
- if (useStdin && file) {
447
- process.stdout.write("Cannot read from both STDIN and file\n");
448
- process.exit(1);
449
- }
450
- if (dryRun && json) {
451
- process.stdout.write("--dry-run cannot be used with --json\n");
452
- process.exit(1);
453
- }
454
- try {
455
- const input = await readInput3(useStdin ? void 0 : file);
456
- const result = sanitizeLog3(input, { strict });
457
- if (dryRun) {
458
- renderDryRunReport2(result.matches);
459
- if (failOnDetect && result.matches.length > 0) {
460
- process.exit(1);
461
- }
462
- process.exit(0);
463
- }
464
- writeOutput3(result, { json });
465
- if (summary) {
466
- printSummary2(result.matches);
467
- }
468
- if (failOnDetect && result.matches.length > 0) {
469
- process.exit(1);
470
- }
471
- process.exit(0);
472
- } catch (err) {
473
- process.stdout.write(err?.message || "Unexpected error");
474
- process.stdout.write("\n");
475
- process.exit(2);
476
- }
477
- }
478
- main2();
479
- }
480
- });
481
-
482
385
  // src/cli/index.ts
483
386
  var { readInput: readInput2 } = (init_readInput(), __toCommonJS(readInput_exports));
484
387
  var { writeOutput: writeOutput2 } = (init_writeOutput(), __toCommonJS(writeOutput_exports));
485
- var { printSummary } = require_summary();
388
+ var { printSummary: printSummary2 } = (init_summary(), __toCommonJS(summary_exports));
486
389
  var { sanitizeLog: sanitizeLog2 } = (init_sanitizeLog(), __toCommonJS(sanitizeLog_exports));
487
390
  var rawArgs = process.argv.slice(2).map((arg) => arg === "-h" ? "--help" : arg);
488
391
  function getVersion() {
489
- return true ? "0.3.5" : "unknown";
392
+ return true ? "0.3.6" : "unknown";
490
393
  }
491
394
  function printHelp() {
492
395
  process.stdout.write(`Usage: logshield scan [file]
@@ -586,6 +489,10 @@ async function main() {
586
489
  process.stdout.write("--dry-run cannot be used with --json\n");
587
490
  process.exit(1);
588
491
  }
492
+ if (json && summary) {
493
+ process.stdout.write("--summary cannot be used with --json\n");
494
+ process.exit(1);
495
+ }
589
496
  try {
590
497
  const input = await readInput2(useStdin ? void 0 : file);
591
498
  const result = sanitizeLog2(input, { strict });
@@ -598,7 +505,7 @@ async function main() {
598
505
  }
599
506
  writeOutput2(result, { json });
600
507
  if (summary) {
601
- printSummary(result.matches);
508
+ printSummary2(result.matches);
602
509
  }
603
510
  if (failOnDetect && result.matches.length > 0) {
604
511
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "logshield-cli",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "license": "ISC",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -15,6 +15,7 @@
15
15
  "scripts": {
16
16
  "build": "node scripts/build-cli.cjs",
17
17
  "build:web": "vite build --outDir dist-web",
18
+ "build:blog": "node scripts/build-blog.js",
18
19
  "dev:web": "vite",
19
20
  "pretest": "npm run build",
20
21
  "test": "vitest",