euredact 0.3.9 → 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.
- package/README.md +313 -25
- package/dist/cjs/cache.js +5 -0
- package/dist/cjs/cloud/client.js +243 -0
- package/dist/cjs/cloud/config.js +57 -0
- package/dist/cjs/cloud/errors.js +55 -0
- package/dist/cjs/cloud/index.js +31 -0
- package/dist/cjs/index.js +23 -3
- package/dist/cjs/rules/countries/index.js +24 -5
- package/dist/cjs/sdk.js +442 -29
- package/dist/cjs/types.js +45 -1
- package/dist/esm/cache.d.ts +2 -0
- package/dist/esm/cache.js +5 -1
- package/dist/esm/cloud/client.d.ts +42 -0
- package/dist/esm/cloud/client.js +239 -0
- package/dist/esm/cloud/config.d.ts +43 -0
- package/dist/esm/cloud/config.js +51 -0
- package/dist/esm/cloud/errors.d.ts +32 -0
- package/dist/esm/cloud/errors.js +48 -0
- package/dist/esm/cloud/index.d.ts +19 -0
- package/dist/esm/cloud/index.js +19 -0
- package/dist/esm/index.d.ts +11 -3
- package/dist/esm/index.js +12 -2
- package/dist/esm/rules/countries/index.js +24 -5
- package/dist/esm/sdk.d.ts +128 -1
- package/dist/esm/sdk.js +405 -28
- package/dist/esm/types.d.ts +63 -1
- package/dist/esm/types.js +44 -1
- package/package.json +7 -3
package/dist/esm/types.d.ts
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
export declare enum EntityType {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Canonical name for a person's name. `NAME` is kept below as a legacy alias
|
|
4
|
+
* with the same value, exactly as `IBAN` aliases `BANK_ACCOUNT`, so
|
|
5
|
+
* `EntityType.NAME === EntityType.PERSON_NAME` and existing code keeps
|
|
6
|
+
* working — but the emitted value, and therefore the `[PERSON_NAME]`
|
|
7
|
+
* placeholder written into redacted text, is canonical.
|
|
8
|
+
*
|
|
9
|
+
* Renamed rather than translated at the cloud boundary: two names for one
|
|
10
|
+
* type is how a whole category goes missing when someone filters on the
|
|
11
|
+
* spelling they happened to know. Nothing could have depended on the old
|
|
12
|
+
* value — the type is cloud-only and the cloud tier was stubbed, so it was
|
|
13
|
+
* never emitted.
|
|
14
|
+
*/
|
|
15
|
+
PERSON_NAME = "PERSON_NAME",
|
|
16
|
+
/** @deprecated legacy alias of {@link EntityType.PERSON_NAME} */
|
|
17
|
+
NAME = "PERSON_NAME",
|
|
3
18
|
ADDRESS = "ADDRESS",
|
|
4
19
|
/**
|
|
5
20
|
* Canonical name for a bank account identifier. `IBAN` is kept below as a
|
|
@@ -47,6 +62,15 @@ export declare enum EntityType {
|
|
|
47
62
|
UUID = "UUID",
|
|
48
63
|
SOCIAL_HANDLE = "SOCIAL_HANDLE",
|
|
49
64
|
SECRET = "SECRET",
|
|
65
|
+
ORGANISATION_NAME = "ORGANISATION_NAME",
|
|
66
|
+
JOB_TITLE = "JOB_TITLE",
|
|
67
|
+
MEDICAL_CONDITION = "MEDICAL_CONDITION",
|
|
68
|
+
SENSITIVE_ATTRIBUTE = "SENSITIVE_ATTRIBUTE",
|
|
69
|
+
BIOMETRIC_REF = "BIOMETRIC_REF",
|
|
70
|
+
FINANCIAL_AMOUNT = "FINANCIAL_AMOUNT",
|
|
71
|
+
QUASI_IDENTIFIER = "QUASI_IDENTIFIER",
|
|
72
|
+
CREDENTIAL = "CREDENTIAL",
|
|
73
|
+
URL = "URL",
|
|
50
74
|
OTHER = "OTHER"
|
|
51
75
|
}
|
|
52
76
|
/**
|
|
@@ -55,6 +79,14 @@ export declare enum EntityType {
|
|
|
55
79
|
* legacy_aliases). The engine never *emits* these names.
|
|
56
80
|
*/
|
|
57
81
|
export declare const LEGACY_TYPE_ALIASES: Record<string, string>;
|
|
82
|
+
/**
|
|
83
|
+
* Resolve a possibly-legacy type name to its canonical form.
|
|
84
|
+
*
|
|
85
|
+
* Mirrors `EntityType._missing_` in the Python SDK. An unrecognised name is
|
|
86
|
+
* returned unchanged rather than dropped: a client one release behind the
|
|
87
|
+
* service must not silently lose a whole category of PII.
|
|
88
|
+
*/
|
|
89
|
+
export declare function canonicalType(name: string): string;
|
|
58
90
|
export declare enum DetectionSource {
|
|
59
91
|
RULES = "rules",
|
|
60
92
|
CLOUD = "cloud"
|
|
@@ -101,6 +133,24 @@ export interface Detection {
|
|
|
101
133
|
*/
|
|
102
134
|
outOfScope?: boolean;
|
|
103
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* A detection the allowlist kept out of the redacted output.
|
|
138
|
+
*
|
|
139
|
+
* An exemption is a deliberate decision to leave a direct identifier in a
|
|
140
|
+
* document that otherwise claims to be redacted, so it is reported rather than
|
|
141
|
+
* silently dropped: without this, "never detected" and "detected and kept"
|
|
142
|
+
* look identical on the result.
|
|
143
|
+
*/
|
|
144
|
+
export interface Exemption {
|
|
145
|
+
entityType: EntityType | string;
|
|
146
|
+
start: number;
|
|
147
|
+
end: number;
|
|
148
|
+
text: string;
|
|
149
|
+
/** The allowlist entry that matched, as the caller wrote it. */
|
|
150
|
+
rule: string;
|
|
151
|
+
/** `"value"` for the literal allowlist, `"domain"` for allowlistDomains. */
|
|
152
|
+
ruleKind: "value" | "domain";
|
|
153
|
+
}
|
|
104
154
|
export interface RedactResult {
|
|
105
155
|
redactedText: string;
|
|
106
156
|
detections: Detection[];
|
|
@@ -126,6 +176,18 @@ export interface RedactResult {
|
|
|
126
176
|
* already means the tier selector, which {@link RedactResult.source} reports.
|
|
127
177
|
*/
|
|
128
178
|
detectionMode: string;
|
|
179
|
+
/**
|
|
180
|
+
* Token -> original text, populated by `redact(text, { tokenize: true })`.
|
|
181
|
+
*
|
|
182
|
+
* Hand it to `restore()` with the text that came back from wherever the
|
|
183
|
+
* redacted text went. Every token is unique to this call: the same value in
|
|
184
|
+
* another document gets a different token. Treat the mapping as read-only —
|
|
185
|
+
* a cached result shares it with every caller.
|
|
186
|
+
*/
|
|
187
|
+
tokens: Record<string, string>;
|
|
188
|
+
/** Detections the allowlist kept out of the output, with the rule that
|
|
189
|
+
* matched. Empty unless an allowlist was in force. */
|
|
190
|
+
exempted: Exemption[];
|
|
129
191
|
}
|
|
130
192
|
export interface PatternDef {
|
|
131
193
|
entityType: EntityType | string;
|
package/dist/esm/types.js
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
export var EntityType;
|
|
2
2
|
(function (EntityType) {
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Canonical name for a person's name. `NAME` is kept below as a legacy alias
|
|
5
|
+
* with the same value, exactly as `IBAN` aliases `BANK_ACCOUNT`, so
|
|
6
|
+
* `EntityType.NAME === EntityType.PERSON_NAME` and existing code keeps
|
|
7
|
+
* working — but the emitted value, and therefore the `[PERSON_NAME]`
|
|
8
|
+
* placeholder written into redacted text, is canonical.
|
|
9
|
+
*
|
|
10
|
+
* Renamed rather than translated at the cloud boundary: two names for one
|
|
11
|
+
* type is how a whole category goes missing when someone filters on the
|
|
12
|
+
* spelling they happened to know. Nothing could have depended on the old
|
|
13
|
+
* value — the type is cloud-only and the cloud tier was stubbed, so it was
|
|
14
|
+
* never emitted.
|
|
15
|
+
*/
|
|
16
|
+
EntityType["PERSON_NAME"] = "PERSON_NAME";
|
|
17
|
+
/** @deprecated legacy alias of {@link EntityType.PERSON_NAME} */
|
|
18
|
+
EntityType["NAME"] = "PERSON_NAME";
|
|
4
19
|
EntityType["ADDRESS"] = "ADDRESS";
|
|
5
20
|
/**
|
|
6
21
|
* Canonical name for a bank account identifier. `IBAN` is kept below as a
|
|
@@ -48,6 +63,20 @@ export var EntityType;
|
|
|
48
63
|
EntityType["UUID"] = "UUID";
|
|
49
64
|
EntityType["SOCIAL_HANDLE"] = "SOCIAL_HANDLE";
|
|
50
65
|
EntityType["SECRET"] = "SECRET";
|
|
66
|
+
// ── [CLOUD EXTENSION] ────────────────────────────────────────────────────
|
|
67
|
+
// Types only the cloud tier can detect. The rule engine never emits these —
|
|
68
|
+
// there is no shape to match on — which is exactly why they exist: the
|
|
69
|
+
// model's job is what the rules cannot catch. Named to match the detection
|
|
70
|
+
// canon the service is trained and evaluated against.
|
|
71
|
+
EntityType["ORGANISATION_NAME"] = "ORGANISATION_NAME";
|
|
72
|
+
EntityType["JOB_TITLE"] = "JOB_TITLE";
|
|
73
|
+
EntityType["MEDICAL_CONDITION"] = "MEDICAL_CONDITION";
|
|
74
|
+
EntityType["SENSITIVE_ATTRIBUTE"] = "SENSITIVE_ATTRIBUTE";
|
|
75
|
+
EntityType["BIOMETRIC_REF"] = "BIOMETRIC_REF";
|
|
76
|
+
EntityType["FINANCIAL_AMOUNT"] = "FINANCIAL_AMOUNT";
|
|
77
|
+
EntityType["QUASI_IDENTIFIER"] = "QUASI_IDENTIFIER";
|
|
78
|
+
EntityType["CREDENTIAL"] = "CREDENTIAL";
|
|
79
|
+
EntityType["URL"] = "URL";
|
|
51
80
|
EntityType["OTHER"] = "OTHER";
|
|
52
81
|
})(EntityType || (EntityType = {}));
|
|
53
82
|
/**
|
|
@@ -57,7 +86,21 @@ export var EntityType;
|
|
|
57
86
|
*/
|
|
58
87
|
export const LEGACY_TYPE_ALIASES = {
|
|
59
88
|
IBAN: "BANK_ACCOUNT",
|
|
89
|
+
NAME: "PERSON_NAME",
|
|
90
|
+
STREET_ADDRESS: "ADDRESS",
|
|
91
|
+
NATIONALITY_ETHNICITY: "SENSITIVE_ATTRIBUTE",
|
|
60
92
|
};
|
|
93
|
+
/**
|
|
94
|
+
* Resolve a possibly-legacy type name to its canonical form.
|
|
95
|
+
*
|
|
96
|
+
* Mirrors `EntityType._missing_` in the Python SDK. An unrecognised name is
|
|
97
|
+
* returned unchanged rather than dropped: a client one release behind the
|
|
98
|
+
* service must not silently lose a whole category of PII.
|
|
99
|
+
*/
|
|
100
|
+
export function canonicalType(name) {
|
|
101
|
+
const upper = String(name ?? "").trim().toUpperCase();
|
|
102
|
+
return LEGACY_TYPE_ALIASES[upper] ?? upper;
|
|
103
|
+
}
|
|
61
104
|
export var DetectionSource;
|
|
62
105
|
(function (DetectionSource) {
|
|
63
106
|
DetectionSource["RULES"] = "rules";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "euredact",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "European PII redaction SDK -- fast, zero-dependency, rule-based detection and redaction of personal data across 31 European countries",
|
|
5
5
|
"homepage": "https://euredact.dev",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
55
55
|
"postbuild:cjs": "echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json",
|
|
56
56
|
"build": "rm -rf dist && npm run build:esm && npm run build:cjs",
|
|
57
|
-
"test": "npm run test:spec && npm run test:inference && npm run test:conformance",
|
|
57
|
+
"test": "npm run test:spec && npm run test:inference && npm run test:cloud && npm run test:tokenize && npm run test:allowlist && npm run test:eval-scoring && npm run test:conformance",
|
|
58
58
|
"benchmark": "node --import tsx src/__tests__/benchmark.ts",
|
|
59
59
|
"prepublishOnly": "npm run build",
|
|
60
60
|
"test:spec": "node --import tsx src/__tests__/spec.ts",
|
|
@@ -62,7 +62,11 @@
|
|
|
62
62
|
"test:eval:full": "node --max-old-space-size=8192 --import tsx src/__tests__/evalFull.ts",
|
|
63
63
|
"test:conformance": "node --import tsx src/__tests__/conformance.ts",
|
|
64
64
|
"test:inference": "node --import tsx src/__tests__/inference.ts",
|
|
65
|
-
"dump": "node --import tsx src/__tests__/dump.ts"
|
|
65
|
+
"dump": "node --import tsx src/__tests__/dump.ts",
|
|
66
|
+
"test:cloud": "node --import tsx src/__tests__/cloud.ts",
|
|
67
|
+
"test:tokenize": "node --import tsx src/__tests__/tokenize.ts",
|
|
68
|
+
"test:allowlist": "node --import tsx src/__tests__/allowlist.ts",
|
|
69
|
+
"test:eval-scoring": "node --import tsx src/__tests__/evalScoring.ts"
|
|
66
70
|
},
|
|
67
71
|
"devDependencies": {
|
|
68
72
|
"@types/node": "22.10.2",
|