rehydra 0.4.3 → 0.5.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.
Files changed (49) hide show
  1. package/dist/cli/bin.d.ts +3 -0
  2. package/dist/cli/bin.d.ts.map +1 -0
  3. package/dist/cli/bin.js +24 -0
  4. package/dist/cli/bin.js.map +1 -0
  5. package/dist/cli/commands/anonymize.d.ts +3 -0
  6. package/dist/cli/commands/anonymize.d.ts.map +1 -0
  7. package/dist/cli/commands/anonymize.js +132 -0
  8. package/dist/cli/commands/anonymize.js.map +1 -0
  9. package/dist/cli/commands/inspect.d.ts +3 -0
  10. package/dist/cli/commands/inspect.d.ts.map +1 -0
  11. package/dist/cli/commands/inspect.js +73 -0
  12. package/dist/cli/commands/inspect.js.map +1 -0
  13. package/dist/cli/commands/rehydrate.d.ts +3 -0
  14. package/dist/cli/commands/rehydrate.d.ts.map +1 -0
  15. package/dist/cli/commands/rehydrate.js +30 -0
  16. package/dist/cli/commands/rehydrate.js.map +1 -0
  17. package/dist/cli/commands/setup-ner.d.ts +3 -0
  18. package/dist/cli/commands/setup-ner.d.ts.map +1 -0
  19. package/dist/cli/commands/setup-ner.js +41 -0
  20. package/dist/cli/commands/setup-ner.js.map +1 -0
  21. package/dist/cli/main.d.ts +14 -0
  22. package/dist/cli/main.d.ts.map +1 -0
  23. package/dist/cli/main.js +135 -0
  24. package/dist/cli/main.js.map +1 -0
  25. package/dist/cli/utils/color.d.ts +12 -0
  26. package/dist/cli/utils/color.d.ts.map +1 -0
  27. package/dist/cli/utils/color.js +46 -0
  28. package/dist/cli/utils/color.js.map +1 -0
  29. package/dist/cli/utils/errors.d.ts +8 -0
  30. package/dist/cli/utils/errors.d.ts.map +1 -0
  31. package/dist/cli/utils/errors.js +12 -0
  32. package/dist/cli/utils/errors.js.map +1 -0
  33. package/dist/cli/utils/format.d.ts +14 -0
  34. package/dist/cli/utils/format.d.ts.map +1 -0
  35. package/dist/cli/utils/format.js +63 -0
  36. package/dist/cli/utils/format.js.map +1 -0
  37. package/dist/cli/utils/io.d.ts +10 -0
  38. package/dist/cli/utils/io.d.ts.map +1 -0
  39. package/dist/cli/utils/io.js +37 -0
  40. package/dist/cli/utils/io.js.map +1 -0
  41. package/dist/cli/utils/pii-map-file.d.ts +14 -0
  42. package/dist/cli/utils/pii-map-file.d.ts.map +1 -0
  43. package/dist/cli/utils/pii-map-file.js +32 -0
  44. package/dist/cli/utils/pii-map-file.js.map +1 -0
  45. package/dist/cli/utils/progress.d.ts +4 -0
  46. package/dist/cli/utils/progress.d.ts.map +1 -0
  47. package/dist/cli/utils/progress.js +21 -0
  48. package/dist/cli/utils/progress.js.map +1 -0
  49. package/package.json +7 -1
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ // Node 18 does not expose globalThis.crypto by default
3
+ import { webcrypto } from "node:crypto";
4
+ if (globalThis.crypto === undefined) {
5
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
6
+ globalThis.crypto = webcrypto;
7
+ }
8
+ import { run } from "./main.js";
9
+ import { CLIError } from "./utils/errors.js";
10
+ try {
11
+ const exitCode = await run();
12
+ process.exitCode = exitCode;
13
+ }
14
+ catch (err) {
15
+ if (err instanceof CLIError) {
16
+ process.stderr.write(`Error: ${err.message}\n`);
17
+ process.exitCode = err.exitCode;
18
+ }
19
+ else {
20
+ process.stderr.write(`Unexpected error: ${err instanceof Error ? err.message : String(err)}\n`);
21
+ process.exitCode = 1;
22
+ }
23
+ }
24
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AAEA,uDAAuD;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;IACpC,uGAAuG;IACvG,UAAU,CAAC,MAAM,GAAG,SAAgB,CAAC;AACvC,CAAC;AAED,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,IAAI,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,GAAG,EAAE,CAAC;IAC7B,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;AAC9B,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QAChD,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qBAAqB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC1E,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ParsedOptions } from "../main.js";
2
+ export declare function anonymizeCommand(filePath: string | undefined, options: ParsedOptions): Promise<number>;
3
+ //# sourceMappingURL=anonymize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anonymize.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/anonymize.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAwDhD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAyGjB"}
@@ -0,0 +1,132 @@
1
+ import { createAnonymizer, PIIType, mergePolicy, generateKey, uint8ArrayToBase64, ConfigKeyProvider, } from "../../index.js";
2
+ import { CLIError } from "../utils/errors.js";
3
+ import { readInput, writeOutput } from "../utils/io.js";
4
+ import { formatText, formatJson, formatNdjson, formatStats } from "../utils/format.js";
5
+ import { savePIIMapFile } from "../utils/pii-map-file.js";
6
+ function parseTypes(typesStr) {
7
+ const allValues = new Set(Object.values(PIIType));
8
+ const types = new Set();
9
+ for (const raw of typesStr.split(",")) {
10
+ const t = raw.trim().toUpperCase();
11
+ if (t === "")
12
+ continue;
13
+ if (!allValues.has(t)) {
14
+ throw new CLIError(`Unknown PII type: ${raw.trim()}\nValid types: ${[...allValues].join(", ")}`);
15
+ }
16
+ types.add(t);
17
+ }
18
+ if (types.size === 0) {
19
+ throw new CLIError("--types must specify at least one PII type");
20
+ }
21
+ return types;
22
+ }
23
+ function validateNerMode(mode) {
24
+ const valid = ["disabled", "quantized", "standard"];
25
+ if (!valid.includes(mode)) {
26
+ throw new CLIError(`Invalid NER mode: ${mode}\nValid modes: ${valid.join(", ")}`);
27
+ }
28
+ return mode;
29
+ }
30
+ function validateMode(mode) {
31
+ if (mode !== "anonymize" && mode !== "pseudonymize") {
32
+ throw new CLIError(`Invalid mode: ${mode}\nValid modes: anonymize, pseudonymize`);
33
+ }
34
+ return mode;
35
+ }
36
+ function validateFormat(format) {
37
+ if (format !== "text" && format !== "json" && format !== "ndjson") {
38
+ throw new CLIError(`Invalid format: ${format}\nValid formats: text, json, ndjson`);
39
+ }
40
+ return format;
41
+ }
42
+ export async function anonymizeCommand(filePath, options) {
43
+ const nerMode = validateNerMode(options.ner);
44
+ const anonMode = validateMode(options.mode);
45
+ const format = validateFormat(options.format);
46
+ const input = await readInput(filePath);
47
+ // Set up encryption key
48
+ const envKey = process.env["REHYDRA_KEY"];
49
+ const flagKey = options.key;
50
+ const externalKey = flagKey ?? envKey;
51
+ let keyBase64;
52
+ let keyProvider;
53
+ if (externalKey !== undefined) {
54
+ keyProvider = new ConfigKeyProvider(externalKey);
55
+ // Don't store the key in the PII map file when user provides it
56
+ }
57
+ else {
58
+ const keyBytes = generateKey();
59
+ keyBase64 = uint8ArrayToBase64(keyBytes);
60
+ keyProvider = new ConfigKeyProvider(keyBase64);
61
+ }
62
+ // Build anonymizer config
63
+ const config = {
64
+ mode: anonMode,
65
+ keyProvider,
66
+ };
67
+ if (nerMode !== "disabled") {
68
+ config.ner = {
69
+ mode: nerMode,
70
+ autoDownload: true,
71
+ onStatus: options.quiet
72
+ ? undefined
73
+ : (status) => {
74
+ process.stderr.write(`${status}\n`);
75
+ },
76
+ };
77
+ }
78
+ // Build policy with type filtering
79
+ const policy = options.types !== undefined
80
+ ? mergePolicy({ enabledTypes: parseTypes(options.types) })
81
+ : undefined;
82
+ const anonymizer = createAnonymizer(config);
83
+ await anonymizer.initialize();
84
+ try {
85
+ const result = await anonymizer.anonymize(input, options.locale, policy !== undefined ? policy : undefined);
86
+ // Save PII map file in pseudonymize mode
87
+ if (anonMode === "pseudonymize" && result.piiMap !== undefined) {
88
+ const piiMapFile = {
89
+ version: 1,
90
+ createdAt: new Date().toISOString(),
91
+ ...(keyBase64 !== undefined ? { key: keyBase64 } : {}),
92
+ piiMap: result.piiMap,
93
+ stats: {
94
+ totalEntities: result.stats.totalEntities,
95
+ countsByType: result.stats.countsByType,
96
+ },
97
+ };
98
+ await savePIIMapFile(options["pii-map"], piiMapFile);
99
+ if (!options.quiet) {
100
+ process.stderr.write(`PII map saved to ${options["pii-map"]}\n`);
101
+ }
102
+ }
103
+ // Format output
104
+ let output;
105
+ switch (format) {
106
+ case "text":
107
+ output = formatText(result);
108
+ break;
109
+ case "json":
110
+ output = formatJson(result);
111
+ break;
112
+ case "ndjson":
113
+ output = formatNdjson(result);
114
+ break;
115
+ }
116
+ // Ensure trailing newline
117
+ if (!output.endsWith("\n")) {
118
+ output += "\n";
119
+ }
120
+ await writeOutput(output, options.output);
121
+ // Print stats to stderr if verbose
122
+ if (options.verbose) {
123
+ process.stderr.write(formatStats(result.stats) + "\n");
124
+ }
125
+ // Exit code 2 if no PII found
126
+ return result.stats.totalEntities > 0 ? 0 : 2;
127
+ }
128
+ finally {
129
+ await anonymizer.dispose();
130
+ }
131
+ }
132
+ //# sourceMappingURL=anonymize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anonymize.js","sourceRoot":"","sources":["../../../src/cli/commands/anonymize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ParsedOptions } from "../main.js";
2
+ export declare function inspectCommand(filePath: string | undefined, options: ParsedOptions): Promise<number>;
3
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/inspect.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA8BhD,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAmDjB"}
@@ -0,0 +1,73 @@
1
+ import { createAnonymizer, PIIType, mergePolicy, InMemoryKeyProvider, } from "../../index.js";
2
+ import { CLIError } from "../utils/errors.js";
3
+ import { readInput, writeOutput } from "../utils/io.js";
4
+ import { formatInspect, formatStats } from "../utils/format.js";
5
+ function parseTypes(typesStr) {
6
+ const allValues = new Set(Object.values(PIIType));
7
+ const types = new Set();
8
+ for (const raw of typesStr.split(",")) {
9
+ const t = raw.trim().toUpperCase();
10
+ if (t === "")
11
+ continue;
12
+ if (!allValues.has(t)) {
13
+ throw new CLIError(`Unknown PII type: ${raw.trim()}`);
14
+ }
15
+ types.add(t);
16
+ }
17
+ if (types.size === 0) {
18
+ throw new CLIError("--types must specify at least one PII type");
19
+ }
20
+ return types;
21
+ }
22
+ function validateNerMode(mode) {
23
+ const valid = ["disabled", "quantized", "standard"];
24
+ if (!valid.includes(mode)) {
25
+ throw new CLIError(`Invalid NER mode: ${mode}`);
26
+ }
27
+ return mode;
28
+ }
29
+ export async function inspectCommand(filePath, options) {
30
+ const nerMode = validateNerMode(options.ner);
31
+ const input = await readInput(filePath);
32
+ const config = {
33
+ mode: "pseudonymize",
34
+ keyProvider: new InMemoryKeyProvider(),
35
+ };
36
+ if (nerMode !== "disabled") {
37
+ config.ner = {
38
+ mode: nerMode,
39
+ autoDownload: true,
40
+ onStatus: options.quiet
41
+ ? undefined
42
+ : (status) => {
43
+ process.stderr.write(`${status}\n`);
44
+ },
45
+ };
46
+ }
47
+ const policy = options.types !== undefined
48
+ ? mergePolicy({ enabledTypes: parseTypes(options.types) })
49
+ : undefined;
50
+ const anonymizer = createAnonymizer(config);
51
+ await anonymizer.initialize();
52
+ try {
53
+ const result = await anonymizer.anonymize(input, options.locale, policy !== undefined ? policy : undefined);
54
+ // Build inspect entities using offsets from original text
55
+ const inspectEntities = result.entities.map((e) => ({
56
+ type: e.type,
57
+ original: input.slice(e.start, e.end),
58
+ start: e.start,
59
+ end: e.end,
60
+ }));
61
+ const inspectOutput = formatInspect(input, inspectEntities);
62
+ await writeOutput(inspectOutput + "\n", options.output);
63
+ // Always print stats to stderr
64
+ if (!options.quiet) {
65
+ process.stderr.write(formatStats(result.stats) + "\n");
66
+ }
67
+ return result.stats.totalEntities > 0 ? 0 : 2;
68
+ }
69
+ finally {
70
+ await anonymizer.dispose();
71
+ }
72
+ }
73
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../../src/cli/commands/inspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ParsedOptions } from "../main.js";
2
+ export declare function rehydrateCommand(filePath: string | undefined, options: ParsedOptions): Promise<number>;
3
+ //# sourceMappingURL=rehydrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rehydrate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/rehydrate.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
@@ -0,0 +1,30 @@
1
+ import { decryptPIIMap, base64ToUint8Array, rehydrate, } from "../../index.js";
2
+ import { CLIError } from "../utils/errors.js";
3
+ import { readInput, writeOutput } from "../utils/io.js";
4
+ import { loadPIIMapFile } from "../utils/pii-map-file.js";
5
+ export async function rehydrateCommand(filePath, options) {
6
+ const input = await readInput(filePath);
7
+ const piiMapFile = await loadPIIMapFile(options["pii-map"]);
8
+ // Determine encryption key
9
+ const envKey = process.env["REHYDRA_KEY"];
10
+ const flagKey = options.key;
11
+ const externalKey = flagKey ?? envKey;
12
+ const keyBase64 = externalKey ?? piiMapFile.key;
13
+ if (keyBase64 === undefined) {
14
+ throw new CLIError("No encryption key found. Provide --key, set REHYDRA_KEY, or use a PII map file that contains the key.");
15
+ }
16
+ const keyBytes = base64ToUint8Array(keyBase64);
17
+ let rawPiiMap;
18
+ try {
19
+ rawPiiMap = await decryptPIIMap(piiMapFile.piiMap, keyBytes);
20
+ }
21
+ catch {
22
+ throw new CLIError("Failed to decrypt PII map. Check that the encryption key is correct.");
23
+ }
24
+ const output = rehydrate(input, rawPiiMap);
25
+ // Ensure trailing newline
26
+ const finalOutput = output.endsWith("\n") ? output : output + "\n";
27
+ await writeOutput(finalOutput, options.output);
28
+ return 0;
29
+ }
30
+ //# sourceMappingURL=rehydrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rehydrate.js","sourceRoot":"","sources":["../../../src/cli/commands/rehydrate.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,SAAS,GACV,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA4B,EAC5B,OAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAE5D,2BAA2B;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;IAC5B,MAAM,WAAW,GAAG,OAAO,IAAI,MAAM,CAAC;IACtC,MAAM,SAAS,GAAG,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC;IAEhD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,QAAQ,CAChB,uGAAuG,CACxG,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE/C,IAAI,SAAoB,CAAC;IACzB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAChB,sEAAsE,CACvE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAE3C,0BAA0B;IAC1B,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;IACnE,MAAM,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/C,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ParsedOptions } from "../main.js";
2
+ export declare function setupNerCommand(options: ParsedOptions): Promise<number>;
3
+ //# sourceMappingURL=setup-ner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-ner.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup-ner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
@@ -0,0 +1,41 @@
1
+ import { isModelDownloaded, downloadModel, } from "../../index.js";
2
+ import { CLIError } from "../utils/errors.js";
3
+ import { green, bold } from "../utils/color.js";
4
+ import { formatProgress, writeProgress, clearProgress } from "../utils/progress.js";
5
+ export async function setupNerCommand(options) {
6
+ const mode = options.ner === "standard" ? "standard" : "quantized";
7
+ const alreadyDownloaded = await isModelDownloaded(mode);
8
+ if (alreadyDownloaded) {
9
+ if (!options.quiet) {
10
+ process.stderr.write(green(`NER model (${mode}) is already downloaded.\n`));
11
+ }
12
+ return 0;
13
+ }
14
+ if (!options.quiet) {
15
+ process.stderr.write(bold(`Downloading NER model (${mode})...\n`));
16
+ }
17
+ const onProgress = (progress) => {
18
+ if (!options.quiet) {
19
+ writeProgress(formatProgress(progress.file, progress.percent));
20
+ }
21
+ };
22
+ const onStatus = options.quiet
23
+ ? undefined
24
+ : (status) => {
25
+ clearProgress();
26
+ process.stderr.write(`${status}\n`);
27
+ };
28
+ try {
29
+ await downloadModel(mode, onProgress, onStatus);
30
+ }
31
+ catch (err) {
32
+ clearProgress();
33
+ throw new CLIError(`Failed to download NER model: ${err instanceof Error ? err.message : String(err)}`);
34
+ }
35
+ clearProgress();
36
+ if (!options.quiet) {
37
+ process.stderr.write(green(`\nNER model (${mode}) downloaded successfully.\n`));
38
+ }
39
+ return 0;
40
+ }
41
+ //# sourceMappingURL=setup-ner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-ner.js","sourceRoot":"","sources":["../../../src/cli/commands/setup-ner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,aAAa,GAEd,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAsB;IAEtB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;IAEnE,MAAM,iBAAiB,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,iBAAiB,EAAE,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,cAAc,IAAI,4BAA4B,CAAC,CACtD,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,0BAA0B,IAAI,QAAQ,CAAC,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAA6B,CAAC,QAAQ,EAAE,EAAE;QACxD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,aAAa,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK;QAC5B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,CAAC,MAAc,EAAQ,EAAE;YACvB,aAAa,EAAE,CAAC;YAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC;IAEN,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,EAAE,CAAC;QAChB,MAAM,IAAI,QAAQ,CAChB,iCAAiC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACpF,CAAC;IACJ,CAAC;IAED,aAAa,EAAE,CAAC;IAChB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,IAAI,8BAA8B,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface ParsedOptions {
2
+ output?: string;
3
+ format: string;
4
+ ner: string;
5
+ "pii-map": string;
6
+ key?: string;
7
+ types?: string;
8
+ mode: string;
9
+ locale?: string;
10
+ verbose: boolean;
11
+ quiet: boolean;
12
+ }
13
+ export declare function run(argv?: string[]): Promise<number>;
14
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAmDD,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAmFjF"}
@@ -0,0 +1,135 @@
1
+ import { parseArgs } from "node:util";
2
+ import { createRequire } from "node:module";
3
+ import { setNoColor, red, bold, dim } from "./utils/color.js";
4
+ import { anonymizeCommand } from "./commands/anonymize.js";
5
+ import { rehydrateCommand } from "./commands/rehydrate.js";
6
+ import { inspectCommand } from "./commands/inspect.js";
7
+ import { setupNerCommand } from "./commands/setup-ner.js";
8
+ const require = createRequire(import.meta.url);
9
+ const pkg = require("../../package.json");
10
+ const HELP_TEXT = `
11
+ ${bold("rehydra")} — PII anonymization CLI
12
+
13
+ ${bold("USAGE")}
14
+ rehydra <command> [file] [options]
15
+
16
+ ${bold("COMMANDS")}
17
+ anonymize <file> Anonymize a file or stdin
18
+ rehydrate <file> Rehydrate a previously anonymized file
19
+ inspect <file> Show detected PII without anonymizing (dry run)
20
+ setup-ner Download and set up NER model
21
+
22
+ ${bold("OPTIONS")}
23
+ -o, --output <file> Output file (default: stdout)
24
+ -f, --format <format> Output format: text, json, ndjson (default: text)
25
+ --ner <mode> NER mode: disabled, quantized, standard (default: disabled)
26
+ --pii-map <file> PII map file path (default: .rehydra-pii-map.json)
27
+ --key <key> Encryption key (or set REHYDRA_KEY env var)
28
+ --types <types> Comma-separated PII types to detect (default: all)
29
+ --mode <mode> anonymize | pseudonymize (default: pseudonymize)
30
+ --locale <locale> Locale hint for detection (e.g., de-DE)
31
+ --no-color Disable colored output
32
+ --verbose Show detection details
33
+ -q, --quiet Suppress non-essential output
34
+ -h, --help Show this help
35
+ -V, --version Show version
36
+
37
+ ${bold("EXAMPLES")}
38
+ ${dim("# Anonymize a file")}
39
+ rehydra anonymize input.txt -o output.txt
40
+
41
+ ${dim("# Pipe from stdin")}
42
+ cat data.csv | rehydra anonymize > anonymized.csv
43
+
44
+ ${dim("# JSON output with NER")}
45
+ rehydra anonymize input.txt --ner quantized -f json
46
+
47
+ ${dim("# Rehydrate")}
48
+ rehydra rehydrate anonymized.txt --pii-map .rehydra-pii-map.json
49
+
50
+ ${dim("# Inspect detected PII")}
51
+ rehydra inspect input.txt
52
+
53
+ ${bold("EXIT CODES")}
54
+ 0 Success
55
+ 1 Error
56
+ 2 No PII found
57
+ `;
58
+ export async function run(argv = process.argv.slice(2)) {
59
+ let values;
60
+ let positionals;
61
+ try {
62
+ const parsed = parseArgs({
63
+ args: argv,
64
+ options: {
65
+ output: { type: "string", short: "o" },
66
+ format: { type: "string", short: "f", default: "text" },
67
+ ner: { type: "string", default: "disabled" },
68
+ "pii-map": { type: "string", default: ".rehydra-pii-map.json" },
69
+ key: { type: "string" },
70
+ types: { type: "string" },
71
+ mode: { type: "string", default: "pseudonymize" },
72
+ locale: { type: "string" },
73
+ "no-color": { type: "boolean", default: false },
74
+ verbose: { type: "boolean", default: false },
75
+ quiet: { type: "boolean", short: "q", default: false },
76
+ help: { type: "boolean", short: "h", default: false },
77
+ version: { type: "boolean", short: "V", default: false },
78
+ },
79
+ allowPositionals: true,
80
+ strict: true,
81
+ });
82
+ values = parsed.values;
83
+ positionals = parsed.positionals;
84
+ }
85
+ catch (err) {
86
+ const msg = err instanceof Error ? err.message : String(err);
87
+ process.stderr.write(red(`Error: ${msg}\n`));
88
+ process.stderr.write(`Run ${dim("rehydra --help")} for usage.\n`);
89
+ return 1;
90
+ }
91
+ if (values["no-color"] === true) {
92
+ setNoColor(true);
93
+ }
94
+ if (values["help"] === true) {
95
+ process.stdout.write(HELP_TEXT);
96
+ return 0;
97
+ }
98
+ if (values["version"] === true) {
99
+ process.stdout.write(`rehydra ${pkg.version}\n`);
100
+ return 0;
101
+ }
102
+ const command = positionals[0];
103
+ const filePath = positionals[1];
104
+ if (command === undefined) {
105
+ process.stdout.write(HELP_TEXT);
106
+ return 0;
107
+ }
108
+ const options = {
109
+ output: values["output"],
110
+ format: values["format"] ?? "text",
111
+ ner: values["ner"] ?? "disabled",
112
+ "pii-map": values["pii-map"] ?? ".rehydra-pii-map.json",
113
+ key: values["key"],
114
+ types: values["types"],
115
+ mode: values["mode"] ?? "pseudonymize",
116
+ locale: values["locale"],
117
+ verbose: values["verbose"] === true,
118
+ quiet: values["quiet"] === true,
119
+ };
120
+ switch (command) {
121
+ case "anonymize":
122
+ return anonymizeCommand(filePath, options);
123
+ case "rehydrate":
124
+ return rehydrateCommand(filePath, options);
125
+ case "inspect":
126
+ return inspectCommand(filePath, options);
127
+ case "setup-ner":
128
+ return setupNerCommand(options);
129
+ default:
130
+ process.stderr.write(red(`Unknown command: ${command}\n`));
131
+ process.stderr.write(`Run ${dim("rehydra --help")} for usage.\n`);
132
+ return 1;
133
+ }
134
+ }
135
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { PIIType } from "../../types/index.js";
2
+ export declare function setNoColor(value: boolean): void;
3
+ export declare const red: (text: string) => string;
4
+ export declare const green: (text: string) => string;
5
+ export declare const yellow: (text: string) => string;
6
+ export declare const blue: (text: string) => string;
7
+ export declare const magenta: (text: string) => string;
8
+ export declare const cyan: (text: string) => string;
9
+ export declare const dim: (text: string) => string;
10
+ export declare const bold: (text: string) => string;
11
+ export declare function piiTypeColor(type: PIIType): (text: string) => string;
12
+ //# sourceMappingURL=color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/color.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAI/C,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE/C;AAYD,eAAO,MAAM,GAAG,SAJmC,MAAM,KAAK,MAIf,CAAC;AAChD,eAAO,MAAM,KAAK,SALiC,MAAM,KAAK,MAKb,CAAC;AAClD,eAAO,MAAM,MAAM,SANgC,MAAM,KAAK,MAMZ,CAAC;AACnD,eAAO,MAAM,IAAI,SAPkC,MAAM,KAAK,MAOd,CAAC;AACjD,eAAO,MAAM,OAAO,SAR+B,MAAM,KAAK,MAQX,CAAC;AACpD,eAAO,MAAM,IAAI,SATkC,MAAM,KAAK,MASd,CAAC;AACjD,eAAO,MAAM,GAAG,SAVmC,MAAM,KAAK,MAUhB,CAAC;AAC/C,eAAO,MAAM,IAAI,SAXkC,MAAM,KAAK,MAWf,CAAC;AAsBhD,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAEpE"}
@@ -0,0 +1,46 @@
1
+ import { PIIType } from "../../types/index.js";
2
+ let _noColor;
3
+ export function setNoColor(value) {
4
+ _noColor = value;
5
+ }
6
+ function shouldColorize() {
7
+ if (_noColor === true)
8
+ return false;
9
+ if (process.env["NO_COLOR"] !== undefined)
10
+ return false;
11
+ return process.stderr.isTTY === true;
12
+ }
13
+ function wrap(code, reset) {
14
+ return (text) => (shouldColorize() ? `${code}${text}${reset}` : text);
15
+ }
16
+ export const red = wrap("\x1b[31m", "\x1b[39m");
17
+ export const green = wrap("\x1b[32m", "\x1b[39m");
18
+ export const yellow = wrap("\x1b[33m", "\x1b[39m");
19
+ export const blue = wrap("\x1b[34m", "\x1b[39m");
20
+ export const magenta = wrap("\x1b[35m", "\x1b[39m");
21
+ export const cyan = wrap("\x1b[36m", "\x1b[39m");
22
+ export const dim = wrap("\x1b[2m", "\x1b[22m");
23
+ export const bold = wrap("\x1b[1m", "\x1b[22m");
24
+ const TYPE_COLORS = {
25
+ [PIIType.PERSON]: magenta,
26
+ [PIIType.ORG]: blue,
27
+ [PIIType.LOCATION]: green,
28
+ [PIIType.ADDRESS]: green,
29
+ [PIIType.EMAIL]: cyan,
30
+ [PIIType.PHONE]: cyan,
31
+ [PIIType.URL]: cyan,
32
+ [PIIType.IP_ADDRESS]: cyan,
33
+ [PIIType.IBAN]: yellow,
34
+ [PIIType.BIC_SWIFT]: yellow,
35
+ [PIIType.ACCOUNT_NUMBER]: yellow,
36
+ [PIIType.CREDIT_CARD]: yellow,
37
+ [PIIType.TAX_ID]: red,
38
+ [PIIType.NATIONAL_ID]: red,
39
+ [PIIType.DATE_OF_BIRTH]: red,
40
+ [PIIType.CASE_ID]: dim,
41
+ [PIIType.CUSTOMER_ID]: dim,
42
+ };
43
+ export function piiTypeColor(type) {
44
+ return TYPE_COLORS[type] ?? dim;
45
+ }
46
+ //# sourceMappingURL=color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","sourceRoot":"","sources":["../../../src/cli/utils/color.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,IAAI,QAA6B,CAAC;AAElC,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,QAAQ,GAAG,KAAK,CAAC;AACnB,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxD,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;AACvC,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,KAAa;IACvC,OAAO,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAClD,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AACnD,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AACjD,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AACpD,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AACjD,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAC/C,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAEhD,MAAM,WAAW,GAA6C;IAC5D,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO;IACzB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI;IACnB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,KAAK;IACzB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK;IACxB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI;IACrB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI;IACrB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI;IACnB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI;IAC1B,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM;IACtB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM;IAC3B,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM;IAChC,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM;IAC7B,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG;IACrB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG;IAC1B,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,GAAG;IAC5B,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG;IACtB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG;CAC3B,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;AAClC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * CLI-specific error with exit code
3
+ */
4
+ export declare class CLIError extends Error {
5
+ readonly exitCode: number;
6
+ constructor(message: string, exitCode?: number);
7
+ }
8
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAGf,QAAQ,EAAE,MAAM;gBADhC,OAAO,EAAE,MAAM,EACC,QAAQ,GAAE,MAAU;CAKvC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * CLI-specific error with exit code
3
+ */
4
+ export class CLIError extends Error {
5
+ exitCode;
6
+ constructor(message, exitCode = 1) {
7
+ super(message);
8
+ this.exitCode = exitCode;
9
+ this.name = "CLIError";
10
+ }
11
+ }
12
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/cli/utils/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGf;IAFlB,YACE,OAAe,EACC,WAAmB,CAAC;QAEpC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,aAAQ,GAAR,QAAQ,CAAY;QAGpC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ import type { AnonymizationResult, AnonymizationStats, PIIType } from "../../types/index.js";
2
+ export declare function formatText(result: AnonymizationResult): string;
3
+ export declare function formatJson(result: AnonymizationResult): string;
4
+ export declare function formatNdjson(result: AnonymizationResult): string;
5
+ interface InspectEntity {
6
+ type: PIIType;
7
+ original: string;
8
+ start: number;
9
+ end: number;
10
+ }
11
+ export declare function formatInspect(originalText: string, entities: InspectEntity[]): string;
12
+ export declare function formatStats(stats: AnonymizationStats): string;
13
+ export {};
14
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,OAAO,EACR,MAAM,sBAAsB,CAAC;AAG9B,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAE9D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAiB9D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAoBhE;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,aAAa,CAC3B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,aAAa,EAAE,GACxB,MAAM,CAYR;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAa7D"}
@@ -0,0 +1,63 @@
1
+ import { bold, dim, piiTypeColor } from "./color.js";
2
+ export function formatText(result) {
3
+ return result.anonymizedText;
4
+ }
5
+ export function formatJson(result) {
6
+ const output = {
7
+ anonymizedText: result.anonymizedText,
8
+ entities: result.entities.map((e) => ({
9
+ type: e.type,
10
+ id: e.id,
11
+ confidence: e.confidence,
12
+ source: e.source,
13
+ ...(e.semantic !== undefined ? { semantic: e.semantic } : {}),
14
+ })),
15
+ stats: {
16
+ totalEntities: result.stats.totalEntities,
17
+ countsByType: result.stats.countsByType,
18
+ processingTimeMs: result.stats.processingTimeMs,
19
+ },
20
+ };
21
+ return JSON.stringify(output, null, 2);
22
+ }
23
+ export function formatNdjson(result) {
24
+ const lines = result.entities.map((e) => JSON.stringify({
25
+ type: e.type,
26
+ id: e.id,
27
+ confidence: e.confidence,
28
+ source: e.source,
29
+ ...(e.semantic !== undefined ? { semantic: e.semantic } : {}),
30
+ }));
31
+ // Also include a summary line
32
+ lines.push(JSON.stringify({
33
+ _type: "summary",
34
+ anonymizedText: result.anonymizedText,
35
+ totalEntities: result.stats.totalEntities,
36
+ processingTimeMs: result.stats.processingTimeMs,
37
+ }));
38
+ return lines.join("\n");
39
+ }
40
+ export function formatInspect(originalText, entities) {
41
+ // Sort entities by position descending so replacements don't shift offsets
42
+ const sorted = [...entities].sort((a, b) => b.start - a.start);
43
+ let result = originalText;
44
+ for (const entity of sorted) {
45
+ const colorFn = piiTypeColor(entity.type);
46
+ const label = colorFn(`[${entity.type}: ${entity.original}]`);
47
+ result = result.slice(0, entity.start) + label + result.slice(entity.end);
48
+ }
49
+ return result;
50
+ }
51
+ export function formatStats(stats) {
52
+ const lines = [];
53
+ lines.push(` ${bold("Found")} ${stats.totalEntities} PII ${stats.totalEntities === 1 ? "entity" : "entities"}:`);
54
+ for (const [type, count] of Object.entries(stats.countsByType)) {
55
+ if (count > 0) {
56
+ const colorFn = piiTypeColor(type);
57
+ lines.push(` ${colorFn(type)} ${count}`);
58
+ }
59
+ }
60
+ lines.push(dim(` Processing time: ${stats.processingTimeMs}ms`));
61
+ return lines.join("\n");
62
+ }
63
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/cli/utils/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Read input from a file path or stdin.
3
+ * Throws CLIError if no file and stdin is a TTY (no piped data).
4
+ */
5
+ export declare function readInput(filePath?: string): Promise<string>;
6
+ /**
7
+ * Write output to a file path or stdout.
8
+ */
9
+ export declare function writeOutput(data: string, filePath?: string): Promise<void>;
10
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/io.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAsB,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAMf"}
@@ -0,0 +1,37 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { text } from "node:stream/consumers";
3
+ import { CLIError } from "./errors.js";
4
+ /**
5
+ * Read input from a file path or stdin.
6
+ * Throws CLIError if no file and stdin is a TTY (no piped data).
7
+ */
8
+ export async function readInput(filePath) {
9
+ if (filePath !== undefined) {
10
+ try {
11
+ return await readFile(filePath, "utf-8");
12
+ }
13
+ catch (err) {
14
+ const code = err.code;
15
+ if (code === "ENOENT") {
16
+ throw new CLIError(`File not found: ${filePath}`);
17
+ }
18
+ throw new CLIError(`Failed to read file: ${filePath}`);
19
+ }
20
+ }
21
+ if (process.stdin.isTTY === true) {
22
+ throw new CLIError("No input: provide a file argument or pipe data via stdin");
23
+ }
24
+ return text(process.stdin);
25
+ }
26
+ /**
27
+ * Write output to a file path or stdout.
28
+ */
29
+ export async function writeOutput(data, filePath) {
30
+ if (filePath !== undefined) {
31
+ await writeFile(filePath, data, "utf-8");
32
+ }
33
+ else {
34
+ process.stdout.write(data);
35
+ }
36
+ }
37
+ //# sourceMappingURL=io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.js","sourceRoot":"","sources":["../../../src/cli/utils/io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAiB;IAC/C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;YACjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,IAAI,QAAQ,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;YACpD,CAAC;YACD,MAAM,IAAI,QAAQ,CAAC,wBAAwB,QAAQ,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,QAAQ,CAChB,0DAA0D,CAC3D,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,QAAiB;IAEjB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { EncryptedPIIMap } from "../../types/index.js";
2
+ export interface PIIMapFile {
3
+ version: 1;
4
+ createdAt: string;
5
+ key?: string;
6
+ piiMap: EncryptedPIIMap;
7
+ stats: {
8
+ totalEntities: number;
9
+ countsByType: Record<string, number>;
10
+ };
11
+ }
12
+ export declare function savePIIMapFile(path: string, data: PIIMapFile): Promise<void>;
13
+ export declare function loadPIIMapFile(path: string): Promise<PIIMapFile>;
14
+ //# sourceMappingURL=pii-map-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pii-map-file.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/pii-map-file.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC,CAAC;CACH;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA2BtE"}
@@ -0,0 +1,32 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { CLIError } from "./errors.js";
3
+ export async function savePIIMapFile(path, data) {
4
+ const json = JSON.stringify(data, null, 2) + "\n";
5
+ await writeFile(path, json, "utf-8");
6
+ }
7
+ export async function loadPIIMapFile(path) {
8
+ let raw;
9
+ try {
10
+ raw = await readFile(path, "utf-8");
11
+ }
12
+ catch (err) {
13
+ const code = err.code;
14
+ if (code === "ENOENT") {
15
+ throw new CLIError(`PII map file not found: ${path}`);
16
+ }
17
+ throw new CLIError(`Failed to read PII map file: ${path}`);
18
+ }
19
+ let parsed;
20
+ try {
21
+ parsed = JSON.parse(raw);
22
+ }
23
+ catch {
24
+ throw new CLIError(`Invalid JSON in PII map file: ${path}`);
25
+ }
26
+ const file = parsed;
27
+ if (file.version !== 1 || file.piiMap === undefined) {
28
+ throw new CLIError(`Invalid PII map file format: ${path}`);
29
+ }
30
+ return file;
31
+ }
32
+ //# sourceMappingURL=pii-map-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pii-map-file.js","sourceRoot":"","sources":["../../../src/cli/utils/pii-map-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAavC,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,IAAgB;IAEhB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAClD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,QAAQ,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,IAAI,QAAQ,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,IAAI,GAAG,MAAoB,CAAC;IAClC,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACpD,MAAM,IAAI,QAAQ,CAChB,gCAAgC,IAAI,EAAE,CACvC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function formatProgress(file: string, percent: number | null): string;
2
+ export declare function writeProgress(line: string): void;
3
+ export declare function clearProgress(): void;
4
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/progress.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,MAAM,CASR;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIhD;AAED,wBAAgB,aAAa,IAAI,IAAI,CAIpC"}
@@ -0,0 +1,21 @@
1
+ const BAR_WIDTH = 30;
2
+ export function formatProgress(file, percent) {
3
+ if (percent === null) {
4
+ return ` Downloading ${file}...`;
5
+ }
6
+ const filled = Math.round((percent / 100) * BAR_WIDTH);
7
+ const empty = BAR_WIDTH - filled;
8
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
9
+ return ` ${file} [${bar}] ${percent.toFixed(0)}%`;
10
+ }
11
+ export function writeProgress(line) {
12
+ if (process.stderr.isTTY === true) {
13
+ process.stderr.write(`\r\x1b[K${line}`);
14
+ }
15
+ }
16
+ export function clearProgress() {
17
+ if (process.stderr.isTTY === true) {
18
+ process.stderr.write("\r\x1b[K");
19
+ }
20
+ }
21
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../../src/cli/utils/progress.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,OAAsB;IAEtB,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,iBAAiB,IAAI,KAAK,CAAC;IACpC,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7D,OAAO,KAAK,IAAI,KAAK,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rehydra",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "description": "On-device PII anonymization module for high-privacy AI workflows",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -59,6 +59,12 @@
59
59
  "types": "./dist/proxy/index.d.ts",
60
60
  "default": "./dist/proxy/index.js"
61
61
  }
62
+ },
63
+ "./cli": {
64
+ "node": {
65
+ "types": "./dist/cli/main.d.ts",
66
+ "default": "./dist/cli/main.js"
67
+ }
62
68
  }
63
69
  },
64
70
  "files": [