@blindfold/sdk 1.0.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 +176 -0
- package/dist/index.d.mts +285 -0
- package/dist/index.d.ts +285 -0
- package/dist/index.js +196 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +190 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Blindfold JS SDK
|
|
2
|
+
|
|
3
|
+
The official JavaScript/TypeScript SDK for Blindfold - The Privacy API for AI.
|
|
4
|
+
|
|
5
|
+
Securely tokenize, mask, redact, and encrypt sensitive data (PII) before sending it to LLMs or third-party services.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @blindfold/sdk
|
|
11
|
+
# or
|
|
12
|
+
yarn add @blindfold/sdk
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @blindfold/sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Initialization
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { Blindfold } from '@blindfold/sdk';
|
|
23
|
+
|
|
24
|
+
const client = new Blindfold({
|
|
25
|
+
apiKey: 'your-api-key-here',
|
|
26
|
+
// Optional: Track specific end-user for audit logs
|
|
27
|
+
userId: 'user_123'
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Tokenize (Reversible)
|
|
32
|
+
|
|
33
|
+
Replace sensitive data with reversible tokens (e.g., `<PERSON_1>`).
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
const response = await client.tokenize(
|
|
37
|
+
"Contact John Doe at john@example.com",
|
|
38
|
+
{
|
|
39
|
+
// Optional: Filter specific entities
|
|
40
|
+
entities: ['PERSON', 'EMAIL_ADDRESS'],
|
|
41
|
+
// Optional: Set confidence threshold
|
|
42
|
+
score_threshold: 0.4
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
console.log(response.text);
|
|
47
|
+
// "Contact <PERSON_1> at <EMAIL_ADDRESS_1>"
|
|
48
|
+
|
|
49
|
+
console.log(response.mapping);
|
|
50
|
+
// { "<PERSON_1>": "John Doe", "<EMAIL_ADDRESS_1>": "john@example.com" }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Detokenize
|
|
54
|
+
|
|
55
|
+
Restore original values from tokens.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const original = await client.detokenize(
|
|
59
|
+
"AI response for <PERSON_1>",
|
|
60
|
+
response.mapping
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
console.log(original.text);
|
|
64
|
+
// "AI response for John Doe"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Mask
|
|
68
|
+
|
|
69
|
+
Partially hide sensitive data (e.g., `****-****-****-1234`).
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
const response = await client.mask(
|
|
73
|
+
"Credit card: 4532-7562-9102-3456",
|
|
74
|
+
{
|
|
75
|
+
masking_char: '*',
|
|
76
|
+
chars_to_show: 4,
|
|
77
|
+
from_end: true
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
console.log(response.text);
|
|
82
|
+
// "Credit card: ***************3456"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Redact
|
|
86
|
+
|
|
87
|
+
Permanently remove sensitive data.
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
const response = await client.redact(
|
|
91
|
+
"My password is secret123",
|
|
92
|
+
{
|
|
93
|
+
entities: ['PASSWORD'] // If supported
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Hash
|
|
99
|
+
|
|
100
|
+
Replace data with deterministic hashes (useful for analytics/matching).
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
const response = await client.hash(
|
|
104
|
+
"User ID: 12345",
|
|
105
|
+
{
|
|
106
|
+
hash_type: 'sha256',
|
|
107
|
+
hash_prefix: 'ID_'
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Synthesize
|
|
113
|
+
|
|
114
|
+
Replace real data with realistic fake data.
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const response = await client.synthesize(
|
|
118
|
+
"John lives in New York",
|
|
119
|
+
{
|
|
120
|
+
language: 'en'
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
console.log(response.text);
|
|
125
|
+
// "Michael lives in Boston" (example)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Encrypt
|
|
129
|
+
|
|
130
|
+
Encrypt sensitive data using AES (reversible with key).
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const response = await client.encrypt(
|
|
134
|
+
"Secret message",
|
|
135
|
+
{
|
|
136
|
+
encryption_key: 'your-secure-key-min-16-chars'
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Configuration
|
|
142
|
+
|
|
143
|
+
### Entity Types
|
|
144
|
+
|
|
145
|
+
Common supported entities:
|
|
146
|
+
- `PERSON`
|
|
147
|
+
- `EMAIL_ADDRESS`
|
|
148
|
+
- `PHONE_NUMBER`
|
|
149
|
+
- `CREDIT_CARD`
|
|
150
|
+
- `IP_ADDRESS`
|
|
151
|
+
- `LOCATION`
|
|
152
|
+
- `DATE_TIME`
|
|
153
|
+
- `URL`
|
|
154
|
+
- `IBAN_CODE`
|
|
155
|
+
- `US_SSN`
|
|
156
|
+
- `MEDICAL_LICENSE`
|
|
157
|
+
|
|
158
|
+
### Error Handling
|
|
159
|
+
|
|
160
|
+
The SDK throws typed errors:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { AuthenticationError, APIError, NetworkError } from '@blindfold/sdk';
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
await client.tokenize("...");
|
|
167
|
+
} catch (error) {
|
|
168
|
+
if (error instanceof AuthenticationError) {
|
|
169
|
+
// Handle invalid API key
|
|
170
|
+
} else if (error instanceof APIError) {
|
|
171
|
+
// Handle API error (e.g. validation)
|
|
172
|
+
} else if (error instanceof NetworkError) {
|
|
173
|
+
// Handle network issues
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for Blindfold client
|
|
3
|
+
*/
|
|
4
|
+
interface BlindfoldConfig {
|
|
5
|
+
/** API key for authentication */
|
|
6
|
+
apiKey: string;
|
|
7
|
+
/** Base URL for the API (default: http://localhost:8000/api/public/v1) */
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
/** Optional user ID to track who is making the request */
|
|
10
|
+
userId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Configuration options for tokenization
|
|
14
|
+
*/
|
|
15
|
+
interface TokenizeConfig {
|
|
16
|
+
/** List of entities to detect */
|
|
17
|
+
entities?: string[];
|
|
18
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
19
|
+
score_threshold?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Detected entity information
|
|
23
|
+
*/
|
|
24
|
+
interface DetectedEntity {
|
|
25
|
+
/** Entity type (e.g., PERSON, EMAIL_ADDRESS) */
|
|
26
|
+
entity_type: string;
|
|
27
|
+
/** Original text of the entity */
|
|
28
|
+
text: string;
|
|
29
|
+
/** Start index in text */
|
|
30
|
+
start: number;
|
|
31
|
+
/** End index in text */
|
|
32
|
+
end: number;
|
|
33
|
+
/** Confidence score (0-1) */
|
|
34
|
+
score: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Response from tokenize endpoint
|
|
38
|
+
*/
|
|
39
|
+
interface TokenizeResponse {
|
|
40
|
+
/** Anonymized text with placeholders */
|
|
41
|
+
text: string;
|
|
42
|
+
/** Mapping of tokens to original values */
|
|
43
|
+
mapping: Record<string, string>;
|
|
44
|
+
/** List of detected entities */
|
|
45
|
+
detected_entities: DetectedEntity[];
|
|
46
|
+
/** Count of detected entities */
|
|
47
|
+
entities_count: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Response from detokenize endpoint
|
|
51
|
+
*/
|
|
52
|
+
interface DetokenizeResponse {
|
|
53
|
+
/** Original text with restored values */
|
|
54
|
+
text: string;
|
|
55
|
+
/** Number of replacements made */
|
|
56
|
+
replacements_made: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Configuration options for redaction
|
|
60
|
+
*/
|
|
61
|
+
interface RedactConfig {
|
|
62
|
+
/** Character(s) to use for masking (default: "*") */
|
|
63
|
+
masking_char?: string;
|
|
64
|
+
/** List of entities to detect */
|
|
65
|
+
entities?: string[];
|
|
66
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
67
|
+
score_threshold?: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Response from redact endpoint
|
|
71
|
+
*/
|
|
72
|
+
interface RedactResponse {
|
|
73
|
+
/** Text with PII permanently removed */
|
|
74
|
+
text: string;
|
|
75
|
+
/** List of detected and redacted entities */
|
|
76
|
+
detected_entities: DetectedEntity[];
|
|
77
|
+
/** Number of entities redacted */
|
|
78
|
+
entities_count: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Configuration options for masking
|
|
82
|
+
*/
|
|
83
|
+
interface MaskConfig {
|
|
84
|
+
/** Number of characters to show (default: 3) */
|
|
85
|
+
chars_to_show?: number;
|
|
86
|
+
/** Whether to show characters from the end (default: false) */
|
|
87
|
+
from_end?: boolean;
|
|
88
|
+
/** Character to use for masking (default: "*") */
|
|
89
|
+
masking_char?: string;
|
|
90
|
+
/** List of entities to detect */
|
|
91
|
+
entities?: string[];
|
|
92
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
93
|
+
score_threshold?: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Response from mask endpoint
|
|
97
|
+
*/
|
|
98
|
+
interface MaskResponse {
|
|
99
|
+
/** Text with PII partially masked */
|
|
100
|
+
text: string;
|
|
101
|
+
/** List of detected and masked entities */
|
|
102
|
+
detected_entities: DetectedEntity[];
|
|
103
|
+
/** Number of entities masked */
|
|
104
|
+
entities_count: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Configuration options for synthesis
|
|
108
|
+
*/
|
|
109
|
+
interface SynthesizeConfig {
|
|
110
|
+
/** Language code for synthetic data generation (e.g., 'en', 'cs', 'de') */
|
|
111
|
+
language?: string;
|
|
112
|
+
/** List of entities to detect */
|
|
113
|
+
entities?: string[];
|
|
114
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
115
|
+
score_threshold?: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Response from synthesis endpoint
|
|
119
|
+
*/
|
|
120
|
+
interface SynthesizeResponse {
|
|
121
|
+
/** Text with synthetic fake data */
|
|
122
|
+
text: string;
|
|
123
|
+
/** List of detected and synthesized entities */
|
|
124
|
+
detected_entities: DetectedEntity[];
|
|
125
|
+
/** Number of entities synthesized */
|
|
126
|
+
entities_count: number;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Configuration options for hashing
|
|
130
|
+
*/
|
|
131
|
+
interface HashConfig {
|
|
132
|
+
/** Hash algorithm to use (e.g., 'md5', 'sha1', 'sha256', 'sha512') */
|
|
133
|
+
hash_type?: string;
|
|
134
|
+
/** Prefix to add before hash value (default: 'HASH_') */
|
|
135
|
+
hash_prefix?: string;
|
|
136
|
+
/** Length of hash to display (default: 16) */
|
|
137
|
+
hash_length?: number;
|
|
138
|
+
/** List of entities to detect */
|
|
139
|
+
entities?: string[];
|
|
140
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
141
|
+
score_threshold?: number;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Response from hash endpoint
|
|
145
|
+
*/
|
|
146
|
+
interface HashResponse {
|
|
147
|
+
/** Text with PII replaced by hash values */
|
|
148
|
+
text: string;
|
|
149
|
+
/** List of detected and hashed entities */
|
|
150
|
+
detected_entities: DetectedEntity[];
|
|
151
|
+
/** Number of entities hashed */
|
|
152
|
+
entities_count: number;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Configuration options for encryption
|
|
156
|
+
*/
|
|
157
|
+
interface EncryptConfig {
|
|
158
|
+
/** Optional encryption key (if not provided, tenant key will be used) */
|
|
159
|
+
encryption_key?: string;
|
|
160
|
+
/** List of entities to detect */
|
|
161
|
+
entities?: string[];
|
|
162
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
163
|
+
score_threshold?: number;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Response from encrypt endpoint
|
|
167
|
+
*/
|
|
168
|
+
interface EncryptResponse {
|
|
169
|
+
/** Text with PII encrypted */
|
|
170
|
+
text: string;
|
|
171
|
+
/** List of detected and encrypted entities */
|
|
172
|
+
detected_entities: DetectedEntity[];
|
|
173
|
+
/** Number of entities encrypted */
|
|
174
|
+
entities_count: number;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Error response from API
|
|
178
|
+
*/
|
|
179
|
+
interface APIErrorResponse {
|
|
180
|
+
detail?: string;
|
|
181
|
+
message?: string;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Blindfold client for tokenization and detokenization
|
|
186
|
+
*/
|
|
187
|
+
declare class Blindfold {
|
|
188
|
+
private apiKey;
|
|
189
|
+
private baseUrl;
|
|
190
|
+
private userId?;
|
|
191
|
+
/**
|
|
192
|
+
* Create a new Blindfold client
|
|
193
|
+
* @param config - Configuration options
|
|
194
|
+
*/
|
|
195
|
+
constructor(config: BlindfoldConfig);
|
|
196
|
+
/**
|
|
197
|
+
* Make an authenticated request to the API
|
|
198
|
+
*/
|
|
199
|
+
private request;
|
|
200
|
+
/**
|
|
201
|
+
* Tokenize text by replacing sensitive information with tokens
|
|
202
|
+
* @param text - Text to tokenize
|
|
203
|
+
* @param config - Optional configuration
|
|
204
|
+
* @returns Promise with tokenized text and mapping
|
|
205
|
+
*/
|
|
206
|
+
tokenize(text: string, config?: TokenizeConfig): Promise<TokenizeResponse>;
|
|
207
|
+
/**
|
|
208
|
+
* Detokenize text by replacing tokens with original values
|
|
209
|
+
* @param text - Tokenized text
|
|
210
|
+
* @param mapping - Token mapping from tokenize response
|
|
211
|
+
* @returns Promise with original text
|
|
212
|
+
*/
|
|
213
|
+
detokenize(text: string, mapping: Record<string, string>): Promise<DetokenizeResponse>;
|
|
214
|
+
/**
|
|
215
|
+
* Redact (permanently remove) sensitive information from text
|
|
216
|
+
*
|
|
217
|
+
* WARNING: Redaction is irreversible - original data cannot be restored!
|
|
218
|
+
*
|
|
219
|
+
* @param text - Text to redact
|
|
220
|
+
* @param config - Optional configuration (masking_char, entities)
|
|
221
|
+
* @returns Promise with redacted text and detected entities
|
|
222
|
+
*/
|
|
223
|
+
redact(text: string, config?: RedactConfig): Promise<RedactResponse>;
|
|
224
|
+
/**
|
|
225
|
+
* Mask (partially hide) sensitive information from text
|
|
226
|
+
*
|
|
227
|
+
* @param text - Text to mask
|
|
228
|
+
* @param config - Optional configuration (chars_to_show, from_end, masking_char, entities)
|
|
229
|
+
* @returns Promise with masked text and detected entities
|
|
230
|
+
*/
|
|
231
|
+
mask(text: string, config?: MaskConfig): Promise<MaskResponse>;
|
|
232
|
+
/**
|
|
233
|
+
* Synthesize (replace real data with synthetic fake data)
|
|
234
|
+
*
|
|
235
|
+
* @param text - Text to synthesize
|
|
236
|
+
* @param config - Optional configuration (language, entities)
|
|
237
|
+
* @returns Promise with synthetic text and detected entities
|
|
238
|
+
*/
|
|
239
|
+
synthesize(text: string, config?: SynthesizeConfig): Promise<SynthesizeResponse>;
|
|
240
|
+
/**
|
|
241
|
+
* Hash (replace with deterministic hash values)
|
|
242
|
+
*
|
|
243
|
+
* @param text - Text to hash
|
|
244
|
+
* @param config - Optional configuration (hash_type, hash_prefix, hash_length, entities)
|
|
245
|
+
* @returns Promise with hashed text and detected entities
|
|
246
|
+
*/
|
|
247
|
+
hash(text: string, config?: HashConfig): Promise<HashResponse>;
|
|
248
|
+
/**
|
|
249
|
+
* Encrypt (reversibly protect) sensitive data in text using AES encryption
|
|
250
|
+
*
|
|
251
|
+
* @param text - Text to encrypt
|
|
252
|
+
* @param config - Optional configuration (encryption_key, entities)
|
|
253
|
+
* @returns Promise with encrypted text and detected entities
|
|
254
|
+
*/
|
|
255
|
+
encrypt(text: string, config?: EncryptConfig): Promise<EncryptResponse>;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Base error class for Blindfold SDK
|
|
260
|
+
*/
|
|
261
|
+
declare class BlindfoldError extends Error {
|
|
262
|
+
constructor(message: string);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Error thrown when authentication fails
|
|
266
|
+
*/
|
|
267
|
+
declare class AuthenticationError extends BlindfoldError {
|
|
268
|
+
constructor(message?: string);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Error thrown when API request fails
|
|
272
|
+
*/
|
|
273
|
+
declare class APIError extends BlindfoldError {
|
|
274
|
+
statusCode: number;
|
|
275
|
+
responseBody?: any;
|
|
276
|
+
constructor(message: string, statusCode: number, responseBody?: any);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Error thrown when network request fails
|
|
280
|
+
*/
|
|
281
|
+
declare class NetworkError extends BlindfoldError {
|
|
282
|
+
constructor(message?: string);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export { APIError, type APIErrorResponse, AuthenticationError, Blindfold, type BlindfoldConfig, BlindfoldError, type DetectedEntity, type DetokenizeResponse, NetworkError, type TokenizeConfig, type TokenizeResponse };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for Blindfold client
|
|
3
|
+
*/
|
|
4
|
+
interface BlindfoldConfig {
|
|
5
|
+
/** API key for authentication */
|
|
6
|
+
apiKey: string;
|
|
7
|
+
/** Base URL for the API (default: http://localhost:8000/api/public/v1) */
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
/** Optional user ID to track who is making the request */
|
|
10
|
+
userId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Configuration options for tokenization
|
|
14
|
+
*/
|
|
15
|
+
interface TokenizeConfig {
|
|
16
|
+
/** List of entities to detect */
|
|
17
|
+
entities?: string[];
|
|
18
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
19
|
+
score_threshold?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Detected entity information
|
|
23
|
+
*/
|
|
24
|
+
interface DetectedEntity {
|
|
25
|
+
/** Entity type (e.g., PERSON, EMAIL_ADDRESS) */
|
|
26
|
+
entity_type: string;
|
|
27
|
+
/** Original text of the entity */
|
|
28
|
+
text: string;
|
|
29
|
+
/** Start index in text */
|
|
30
|
+
start: number;
|
|
31
|
+
/** End index in text */
|
|
32
|
+
end: number;
|
|
33
|
+
/** Confidence score (0-1) */
|
|
34
|
+
score: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Response from tokenize endpoint
|
|
38
|
+
*/
|
|
39
|
+
interface TokenizeResponse {
|
|
40
|
+
/** Anonymized text with placeholders */
|
|
41
|
+
text: string;
|
|
42
|
+
/** Mapping of tokens to original values */
|
|
43
|
+
mapping: Record<string, string>;
|
|
44
|
+
/** List of detected entities */
|
|
45
|
+
detected_entities: DetectedEntity[];
|
|
46
|
+
/** Count of detected entities */
|
|
47
|
+
entities_count: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Response from detokenize endpoint
|
|
51
|
+
*/
|
|
52
|
+
interface DetokenizeResponse {
|
|
53
|
+
/** Original text with restored values */
|
|
54
|
+
text: string;
|
|
55
|
+
/** Number of replacements made */
|
|
56
|
+
replacements_made: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Configuration options for redaction
|
|
60
|
+
*/
|
|
61
|
+
interface RedactConfig {
|
|
62
|
+
/** Character(s) to use for masking (default: "*") */
|
|
63
|
+
masking_char?: string;
|
|
64
|
+
/** List of entities to detect */
|
|
65
|
+
entities?: string[];
|
|
66
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
67
|
+
score_threshold?: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Response from redact endpoint
|
|
71
|
+
*/
|
|
72
|
+
interface RedactResponse {
|
|
73
|
+
/** Text with PII permanently removed */
|
|
74
|
+
text: string;
|
|
75
|
+
/** List of detected and redacted entities */
|
|
76
|
+
detected_entities: DetectedEntity[];
|
|
77
|
+
/** Number of entities redacted */
|
|
78
|
+
entities_count: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Configuration options for masking
|
|
82
|
+
*/
|
|
83
|
+
interface MaskConfig {
|
|
84
|
+
/** Number of characters to show (default: 3) */
|
|
85
|
+
chars_to_show?: number;
|
|
86
|
+
/** Whether to show characters from the end (default: false) */
|
|
87
|
+
from_end?: boolean;
|
|
88
|
+
/** Character to use for masking (default: "*") */
|
|
89
|
+
masking_char?: string;
|
|
90
|
+
/** List of entities to detect */
|
|
91
|
+
entities?: string[];
|
|
92
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
93
|
+
score_threshold?: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Response from mask endpoint
|
|
97
|
+
*/
|
|
98
|
+
interface MaskResponse {
|
|
99
|
+
/** Text with PII partially masked */
|
|
100
|
+
text: string;
|
|
101
|
+
/** List of detected and masked entities */
|
|
102
|
+
detected_entities: DetectedEntity[];
|
|
103
|
+
/** Number of entities masked */
|
|
104
|
+
entities_count: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Configuration options for synthesis
|
|
108
|
+
*/
|
|
109
|
+
interface SynthesizeConfig {
|
|
110
|
+
/** Language code for synthetic data generation (e.g., 'en', 'cs', 'de') */
|
|
111
|
+
language?: string;
|
|
112
|
+
/** List of entities to detect */
|
|
113
|
+
entities?: string[];
|
|
114
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
115
|
+
score_threshold?: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Response from synthesis endpoint
|
|
119
|
+
*/
|
|
120
|
+
interface SynthesizeResponse {
|
|
121
|
+
/** Text with synthetic fake data */
|
|
122
|
+
text: string;
|
|
123
|
+
/** List of detected and synthesized entities */
|
|
124
|
+
detected_entities: DetectedEntity[];
|
|
125
|
+
/** Number of entities synthesized */
|
|
126
|
+
entities_count: number;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Configuration options for hashing
|
|
130
|
+
*/
|
|
131
|
+
interface HashConfig {
|
|
132
|
+
/** Hash algorithm to use (e.g., 'md5', 'sha1', 'sha256', 'sha512') */
|
|
133
|
+
hash_type?: string;
|
|
134
|
+
/** Prefix to add before hash value (default: 'HASH_') */
|
|
135
|
+
hash_prefix?: string;
|
|
136
|
+
/** Length of hash to display (default: 16) */
|
|
137
|
+
hash_length?: number;
|
|
138
|
+
/** List of entities to detect */
|
|
139
|
+
entities?: string[];
|
|
140
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
141
|
+
score_threshold?: number;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Response from hash endpoint
|
|
145
|
+
*/
|
|
146
|
+
interface HashResponse {
|
|
147
|
+
/** Text with PII replaced by hash values */
|
|
148
|
+
text: string;
|
|
149
|
+
/** List of detected and hashed entities */
|
|
150
|
+
detected_entities: DetectedEntity[];
|
|
151
|
+
/** Number of entities hashed */
|
|
152
|
+
entities_count: number;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Configuration options for encryption
|
|
156
|
+
*/
|
|
157
|
+
interface EncryptConfig {
|
|
158
|
+
/** Optional encryption key (if not provided, tenant key will be used) */
|
|
159
|
+
encryption_key?: string;
|
|
160
|
+
/** List of entities to detect */
|
|
161
|
+
entities?: string[];
|
|
162
|
+
/** Minimum confidence score for entity detection (0.0-1.0) */
|
|
163
|
+
score_threshold?: number;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Response from encrypt endpoint
|
|
167
|
+
*/
|
|
168
|
+
interface EncryptResponse {
|
|
169
|
+
/** Text with PII encrypted */
|
|
170
|
+
text: string;
|
|
171
|
+
/** List of detected and encrypted entities */
|
|
172
|
+
detected_entities: DetectedEntity[];
|
|
173
|
+
/** Number of entities encrypted */
|
|
174
|
+
entities_count: number;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Error response from API
|
|
178
|
+
*/
|
|
179
|
+
interface APIErrorResponse {
|
|
180
|
+
detail?: string;
|
|
181
|
+
message?: string;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Blindfold client for tokenization and detokenization
|
|
186
|
+
*/
|
|
187
|
+
declare class Blindfold {
|
|
188
|
+
private apiKey;
|
|
189
|
+
private baseUrl;
|
|
190
|
+
private userId?;
|
|
191
|
+
/**
|
|
192
|
+
* Create a new Blindfold client
|
|
193
|
+
* @param config - Configuration options
|
|
194
|
+
*/
|
|
195
|
+
constructor(config: BlindfoldConfig);
|
|
196
|
+
/**
|
|
197
|
+
* Make an authenticated request to the API
|
|
198
|
+
*/
|
|
199
|
+
private request;
|
|
200
|
+
/**
|
|
201
|
+
* Tokenize text by replacing sensitive information with tokens
|
|
202
|
+
* @param text - Text to tokenize
|
|
203
|
+
* @param config - Optional configuration
|
|
204
|
+
* @returns Promise with tokenized text and mapping
|
|
205
|
+
*/
|
|
206
|
+
tokenize(text: string, config?: TokenizeConfig): Promise<TokenizeResponse>;
|
|
207
|
+
/**
|
|
208
|
+
* Detokenize text by replacing tokens with original values
|
|
209
|
+
* @param text - Tokenized text
|
|
210
|
+
* @param mapping - Token mapping from tokenize response
|
|
211
|
+
* @returns Promise with original text
|
|
212
|
+
*/
|
|
213
|
+
detokenize(text: string, mapping: Record<string, string>): Promise<DetokenizeResponse>;
|
|
214
|
+
/**
|
|
215
|
+
* Redact (permanently remove) sensitive information from text
|
|
216
|
+
*
|
|
217
|
+
* WARNING: Redaction is irreversible - original data cannot be restored!
|
|
218
|
+
*
|
|
219
|
+
* @param text - Text to redact
|
|
220
|
+
* @param config - Optional configuration (masking_char, entities)
|
|
221
|
+
* @returns Promise with redacted text and detected entities
|
|
222
|
+
*/
|
|
223
|
+
redact(text: string, config?: RedactConfig): Promise<RedactResponse>;
|
|
224
|
+
/**
|
|
225
|
+
* Mask (partially hide) sensitive information from text
|
|
226
|
+
*
|
|
227
|
+
* @param text - Text to mask
|
|
228
|
+
* @param config - Optional configuration (chars_to_show, from_end, masking_char, entities)
|
|
229
|
+
* @returns Promise with masked text and detected entities
|
|
230
|
+
*/
|
|
231
|
+
mask(text: string, config?: MaskConfig): Promise<MaskResponse>;
|
|
232
|
+
/**
|
|
233
|
+
* Synthesize (replace real data with synthetic fake data)
|
|
234
|
+
*
|
|
235
|
+
* @param text - Text to synthesize
|
|
236
|
+
* @param config - Optional configuration (language, entities)
|
|
237
|
+
* @returns Promise with synthetic text and detected entities
|
|
238
|
+
*/
|
|
239
|
+
synthesize(text: string, config?: SynthesizeConfig): Promise<SynthesizeResponse>;
|
|
240
|
+
/**
|
|
241
|
+
* Hash (replace with deterministic hash values)
|
|
242
|
+
*
|
|
243
|
+
* @param text - Text to hash
|
|
244
|
+
* @param config - Optional configuration (hash_type, hash_prefix, hash_length, entities)
|
|
245
|
+
* @returns Promise with hashed text and detected entities
|
|
246
|
+
*/
|
|
247
|
+
hash(text: string, config?: HashConfig): Promise<HashResponse>;
|
|
248
|
+
/**
|
|
249
|
+
* Encrypt (reversibly protect) sensitive data in text using AES encryption
|
|
250
|
+
*
|
|
251
|
+
* @param text - Text to encrypt
|
|
252
|
+
* @param config - Optional configuration (encryption_key, entities)
|
|
253
|
+
* @returns Promise with encrypted text and detected entities
|
|
254
|
+
*/
|
|
255
|
+
encrypt(text: string, config?: EncryptConfig): Promise<EncryptResponse>;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Base error class for Blindfold SDK
|
|
260
|
+
*/
|
|
261
|
+
declare class BlindfoldError extends Error {
|
|
262
|
+
constructor(message: string);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Error thrown when authentication fails
|
|
266
|
+
*/
|
|
267
|
+
declare class AuthenticationError extends BlindfoldError {
|
|
268
|
+
constructor(message?: string);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Error thrown when API request fails
|
|
272
|
+
*/
|
|
273
|
+
declare class APIError extends BlindfoldError {
|
|
274
|
+
statusCode: number;
|
|
275
|
+
responseBody?: any;
|
|
276
|
+
constructor(message: string, statusCode: number, responseBody?: any);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Error thrown when network request fails
|
|
280
|
+
*/
|
|
281
|
+
declare class NetworkError extends BlindfoldError {
|
|
282
|
+
constructor(message?: string);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export { APIError, type APIErrorResponse, AuthenticationError, Blindfold, type BlindfoldConfig, BlindfoldError, type DetectedEntity, type DetokenizeResponse, NetworkError, type TokenizeConfig, type TokenizeResponse };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/errors.ts
|
|
4
|
+
var BlindfoldError = class _BlindfoldError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "BlindfoldError";
|
|
8
|
+
Object.setPrototypeOf(this, _BlindfoldError.prototype);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var AuthenticationError = class _AuthenticationError extends BlindfoldError {
|
|
12
|
+
constructor(message = "Authentication failed. Please check your API key.") {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = "AuthenticationError";
|
|
15
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var APIError = class _APIError extends BlindfoldError {
|
|
19
|
+
constructor(message, statusCode, responseBody) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "APIError";
|
|
22
|
+
this.statusCode = statusCode;
|
|
23
|
+
this.responseBody = responseBody;
|
|
24
|
+
Object.setPrototypeOf(this, _APIError.prototype);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var NetworkError = class _NetworkError extends BlindfoldError {
|
|
28
|
+
constructor(message = "Network request failed. Please check your connection.") {
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = "NetworkError";
|
|
31
|
+
Object.setPrototypeOf(this, _NetworkError.prototype);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/client.ts
|
|
36
|
+
var DEFAULT_BASE_URL = "https://api.blindfold.dev/api/public/v1";
|
|
37
|
+
var Blindfold = class {
|
|
38
|
+
/**
|
|
39
|
+
* Create a new Blindfold client
|
|
40
|
+
* @param config - Configuration options
|
|
41
|
+
*/
|
|
42
|
+
constructor(config) {
|
|
43
|
+
this.apiKey = config.apiKey;
|
|
44
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
45
|
+
this.userId = config.userId;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Make an authenticated request to the API
|
|
49
|
+
*/
|
|
50
|
+
async request(endpoint, method, body) {
|
|
51
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
52
|
+
const headers = {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
"X-API-Key": this.apiKey
|
|
55
|
+
};
|
|
56
|
+
if (this.userId) {
|
|
57
|
+
headers["X-Blindfold-User-Id"] = this.userId;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const response = await fetch(url, {
|
|
61
|
+
method,
|
|
62
|
+
headers,
|
|
63
|
+
body: body ? JSON.stringify(body) : void 0
|
|
64
|
+
});
|
|
65
|
+
if (response.status === 401 || response.status === 403) {
|
|
66
|
+
throw new AuthenticationError(
|
|
67
|
+
"Authentication failed. Please check your API key."
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
let errorMessage = `API request failed with status ${response.status}`;
|
|
72
|
+
let responseBody;
|
|
73
|
+
try {
|
|
74
|
+
responseBody = await response.json();
|
|
75
|
+
const errorData = responseBody;
|
|
76
|
+
errorMessage = errorData.detail || errorData.message || errorMessage;
|
|
77
|
+
} catch {
|
|
78
|
+
errorMessage = `${errorMessage}: ${response.statusText}`;
|
|
79
|
+
}
|
|
80
|
+
throw new APIError(errorMessage, response.status, responseBody);
|
|
81
|
+
}
|
|
82
|
+
return await response.json();
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (error instanceof AuthenticationError || error instanceof APIError) {
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
88
|
+
throw new NetworkError(
|
|
89
|
+
"Network request failed. Please check your connection and the API URL."
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
throw new NetworkError(
|
|
93
|
+
error instanceof Error ? error.message : "Unknown error occurred"
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Tokenize text by replacing sensitive information with tokens
|
|
99
|
+
* @param text - Text to tokenize
|
|
100
|
+
* @param config - Optional configuration
|
|
101
|
+
* @returns Promise with tokenized text and mapping
|
|
102
|
+
*/
|
|
103
|
+
async tokenize(text, config) {
|
|
104
|
+
return this.request("/tokenize", "POST", {
|
|
105
|
+
text,
|
|
106
|
+
...config
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Detokenize text by replacing tokens with original values
|
|
111
|
+
* @param text - Tokenized text
|
|
112
|
+
* @param mapping - Token mapping from tokenize response
|
|
113
|
+
* @returns Promise with original text
|
|
114
|
+
*/
|
|
115
|
+
async detokenize(text, mapping) {
|
|
116
|
+
return this.request("/detokenize", "POST", {
|
|
117
|
+
text,
|
|
118
|
+
mapping
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Redact (permanently remove) sensitive information from text
|
|
123
|
+
*
|
|
124
|
+
* WARNING: Redaction is irreversible - original data cannot be restored!
|
|
125
|
+
*
|
|
126
|
+
* @param text - Text to redact
|
|
127
|
+
* @param config - Optional configuration (masking_char, entities)
|
|
128
|
+
* @returns Promise with redacted text and detected entities
|
|
129
|
+
*/
|
|
130
|
+
async redact(text, config) {
|
|
131
|
+
return this.request("/redact", "POST", {
|
|
132
|
+
text,
|
|
133
|
+
...config
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Mask (partially hide) sensitive information from text
|
|
138
|
+
*
|
|
139
|
+
* @param text - Text to mask
|
|
140
|
+
* @param config - Optional configuration (chars_to_show, from_end, masking_char, entities)
|
|
141
|
+
* @returns Promise with masked text and detected entities
|
|
142
|
+
*/
|
|
143
|
+
async mask(text, config) {
|
|
144
|
+
return this.request("/mask", "POST", {
|
|
145
|
+
text,
|
|
146
|
+
...config
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Synthesize (replace real data with synthetic fake data)
|
|
151
|
+
*
|
|
152
|
+
* @param text - Text to synthesize
|
|
153
|
+
* @param config - Optional configuration (language, entities)
|
|
154
|
+
* @returns Promise with synthetic text and detected entities
|
|
155
|
+
*/
|
|
156
|
+
async synthesize(text, config) {
|
|
157
|
+
return this.request("/synthesize", "POST", {
|
|
158
|
+
text,
|
|
159
|
+
...config
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Hash (replace with deterministic hash values)
|
|
164
|
+
*
|
|
165
|
+
* @param text - Text to hash
|
|
166
|
+
* @param config - Optional configuration (hash_type, hash_prefix, hash_length, entities)
|
|
167
|
+
* @returns Promise with hashed text and detected entities
|
|
168
|
+
*/
|
|
169
|
+
async hash(text, config) {
|
|
170
|
+
return this.request("/hash", "POST", {
|
|
171
|
+
text,
|
|
172
|
+
...config
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Encrypt (reversibly protect) sensitive data in text using AES encryption
|
|
177
|
+
*
|
|
178
|
+
* @param text - Text to encrypt
|
|
179
|
+
* @param config - Optional configuration (encryption_key, entities)
|
|
180
|
+
* @returns Promise with encrypted text and detected entities
|
|
181
|
+
*/
|
|
182
|
+
async encrypt(text, config) {
|
|
183
|
+
return this.request("/encrypt", "POST", {
|
|
184
|
+
text,
|
|
185
|
+
...config
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
exports.APIError = APIError;
|
|
191
|
+
exports.AuthenticationError = AuthenticationError;
|
|
192
|
+
exports.Blindfold = Blindfold;
|
|
193
|
+
exports.BlindfoldError = BlindfoldError;
|
|
194
|
+
exports.NetworkError = NetworkError;
|
|
195
|
+
//# sourceMappingURL=index.js.map
|
|
196
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Base error class for Blindfold SDK\n */\nexport class BlindfoldError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'BlindfoldError'\n Object.setPrototypeOf(this, BlindfoldError.prototype)\n }\n}\n\n/**\n * Error thrown when authentication fails\n */\nexport class AuthenticationError extends BlindfoldError {\n constructor(message: string = 'Authentication failed. Please check your API key.') {\n super(message)\n this.name = 'AuthenticationError'\n Object.setPrototypeOf(this, AuthenticationError.prototype)\n }\n}\n\n/**\n * Error thrown when API request fails\n */\nexport class APIError extends BlindfoldError {\n statusCode: number\n responseBody?: any\n\n constructor(message: string, statusCode: number, responseBody?: any) {\n super(message)\n this.name = 'APIError'\n this.statusCode = statusCode\n this.responseBody = responseBody\n Object.setPrototypeOf(this, APIError.prototype)\n }\n}\n\n/**\n * Error thrown when network request fails\n */\nexport class NetworkError extends BlindfoldError {\n constructor(message: string = 'Network request failed. Please check your connection.') {\n super(message)\n this.name = 'NetworkError'\n Object.setPrototypeOf(this, NetworkError.prototype)\n }\n}\n","import type {\n BlindfoldConfig,\n TokenizeConfig,\n TokenizeResponse,\n DetokenizeResponse,\n RedactConfig,\n RedactResponse,\n MaskConfig,\n MaskResponse,\n SynthesizeConfig,\n SynthesizeResponse,\n HashConfig,\n HashResponse,\n EncryptConfig,\n EncryptResponse,\n APIErrorResponse,\n} from './types'\nimport { AuthenticationError, APIError, NetworkError } from './errors'\n\nconst DEFAULT_BASE_URL = 'https://api.blindfold.dev/api/public/v1'\n\n/**\n * Blindfold client for tokenization and detokenization\n */\nexport class Blindfold {\n private apiKey: string\n private baseUrl: string\n private userId?: string\n\n /**\n * Create a new Blindfold client\n * @param config - Configuration options\n */\n constructor(config: BlindfoldConfig) {\n this.apiKey = config.apiKey\n this.baseUrl = config.baseUrl || DEFAULT_BASE_URL\n this.userId = config.userId\n }\n\n /**\n * Make an authenticated request to the API\n */\n private async request<T>(\n endpoint: string,\n method: string,\n body?: any\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.apiKey,\n }\n\n if (this.userId) {\n headers['X-Blindfold-User-Id'] = this.userId\n }\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n })\n\n // Handle authentication errors\n if (response.status === 401 || response.status === 403) {\n throw new AuthenticationError(\n 'Authentication failed. Please check your API key.'\n )\n }\n\n // Handle other error responses\n if (!response.ok) {\n let errorMessage = `API request failed with status ${response.status}`\n let responseBody: any\n\n try {\n responseBody = await response.json()\n const errorData = responseBody as APIErrorResponse\n errorMessage = errorData.detail || errorData.message || errorMessage\n } catch {\n // If we can't parse the error response, use the status text\n errorMessage = `${errorMessage}: ${response.statusText}`\n }\n\n throw new APIError(errorMessage, response.status, responseBody)\n }\n\n return (await response.json()) as T\n } catch (error) {\n // Re-throw our custom errors\n if (\n error instanceof AuthenticationError ||\n error instanceof APIError\n ) {\n throw error\n }\n\n // Handle network errors\n if (error instanceof TypeError && error.message.includes('fetch')) {\n throw new NetworkError(\n 'Network request failed. Please check your connection and the API URL.'\n )\n }\n\n // Handle other errors\n throw new NetworkError(\n error instanceof Error ? error.message : 'Unknown error occurred'\n )\n }\n }\n\n /**\n * Tokenize text by replacing sensitive information with tokens\n * @param text - Text to tokenize\n * @param config - Optional configuration\n * @returns Promise with tokenized text and mapping\n */\n async tokenize(\n text: string,\n config?: TokenizeConfig\n ): Promise<TokenizeResponse> {\n return this.request<TokenizeResponse>('/tokenize', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detokenize text by replacing tokens with original values\n * @param text - Tokenized text\n * @param mapping - Token mapping from tokenize response\n * @returns Promise with original text\n */\n async detokenize(\n text: string,\n mapping: Record<string, string>\n ): Promise<DetokenizeResponse> {\n return this.request<DetokenizeResponse>('/detokenize', 'POST', {\n text,\n mapping,\n })\n }\n\n /**\n * Redact (permanently remove) sensitive information from text\n *\n * WARNING: Redaction is irreversible - original data cannot be restored!\n *\n * @param text - Text to redact\n * @param config - Optional configuration (masking_char, entities)\n * @returns Promise with redacted text and detected entities\n */\n async redact(\n text: string,\n config?: RedactConfig\n ): Promise<RedactResponse> {\n return this.request<RedactResponse>('/redact', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Mask (partially hide) sensitive information from text\n *\n * @param text - Text to mask\n * @param config - Optional configuration (chars_to_show, from_end, masking_char, entities)\n * @returns Promise with masked text and detected entities\n */\n async mask(\n text: string,\n config?: MaskConfig\n ): Promise<MaskResponse> {\n return this.request<MaskResponse>('/mask', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Synthesize (replace real data with synthetic fake data)\n *\n * @param text - Text to synthesize\n * @param config - Optional configuration (language, entities)\n * @returns Promise with synthetic text and detected entities\n */\n async synthesize(\n text: string,\n config?: SynthesizeConfig\n ): Promise<SynthesizeResponse> {\n return this.request<SynthesizeResponse>('/synthesize', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Hash (replace with deterministic hash values)\n *\n * @param text - Text to hash\n * @param config - Optional configuration (hash_type, hash_prefix, hash_length, entities)\n * @returns Promise with hashed text and detected entities\n */\n async hash(\n text: string,\n config?: HashConfig\n ): Promise<HashResponse> {\n return this.request<HashResponse>('/hash', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Encrypt (reversibly protect) sensitive data in text using AES encryption\n *\n * @param text - Text to encrypt\n * @param config - Optional configuration (encryption_key, entities)\n * @returns Promise with encrypted text and detected entities\n */\n async encrypt(\n text: string,\n config?: EncryptConfig\n ): Promise<EncryptResponse> {\n return this.request<EncryptResponse>('/encrypt', 'POST', {\n text,\n ...config,\n })\n }\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var BlindfoldError = class _BlindfoldError extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "BlindfoldError";
|
|
6
|
+
Object.setPrototypeOf(this, _BlindfoldError.prototype);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
var AuthenticationError = class _AuthenticationError extends BlindfoldError {
|
|
10
|
+
constructor(message = "Authentication failed. Please check your API key.") {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "AuthenticationError";
|
|
13
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var APIError = class _APIError extends BlindfoldError {
|
|
17
|
+
constructor(message, statusCode, responseBody) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = "APIError";
|
|
20
|
+
this.statusCode = statusCode;
|
|
21
|
+
this.responseBody = responseBody;
|
|
22
|
+
Object.setPrototypeOf(this, _APIError.prototype);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var NetworkError = class _NetworkError extends BlindfoldError {
|
|
26
|
+
constructor(message = "Network request failed. Please check your connection.") {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = "NetworkError";
|
|
29
|
+
Object.setPrototypeOf(this, _NetworkError.prototype);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/client.ts
|
|
34
|
+
var DEFAULT_BASE_URL = "https://api.blindfold.dev/api/public/v1";
|
|
35
|
+
var Blindfold = class {
|
|
36
|
+
/**
|
|
37
|
+
* Create a new Blindfold client
|
|
38
|
+
* @param config - Configuration options
|
|
39
|
+
*/
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this.apiKey = config.apiKey;
|
|
42
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
43
|
+
this.userId = config.userId;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Make an authenticated request to the API
|
|
47
|
+
*/
|
|
48
|
+
async request(endpoint, method, body) {
|
|
49
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
50
|
+
const headers = {
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
"X-API-Key": this.apiKey
|
|
53
|
+
};
|
|
54
|
+
if (this.userId) {
|
|
55
|
+
headers["X-Blindfold-User-Id"] = this.userId;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const response = await fetch(url, {
|
|
59
|
+
method,
|
|
60
|
+
headers,
|
|
61
|
+
body: body ? JSON.stringify(body) : void 0
|
|
62
|
+
});
|
|
63
|
+
if (response.status === 401 || response.status === 403) {
|
|
64
|
+
throw new AuthenticationError(
|
|
65
|
+
"Authentication failed. Please check your API key."
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
let errorMessage = `API request failed with status ${response.status}`;
|
|
70
|
+
let responseBody;
|
|
71
|
+
try {
|
|
72
|
+
responseBody = await response.json();
|
|
73
|
+
const errorData = responseBody;
|
|
74
|
+
errorMessage = errorData.detail || errorData.message || errorMessage;
|
|
75
|
+
} catch {
|
|
76
|
+
errorMessage = `${errorMessage}: ${response.statusText}`;
|
|
77
|
+
}
|
|
78
|
+
throw new APIError(errorMessage, response.status, responseBody);
|
|
79
|
+
}
|
|
80
|
+
return await response.json();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (error instanceof AuthenticationError || error instanceof APIError) {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
86
|
+
throw new NetworkError(
|
|
87
|
+
"Network request failed. Please check your connection and the API URL."
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
throw new NetworkError(
|
|
91
|
+
error instanceof Error ? error.message : "Unknown error occurred"
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Tokenize text by replacing sensitive information with tokens
|
|
97
|
+
* @param text - Text to tokenize
|
|
98
|
+
* @param config - Optional configuration
|
|
99
|
+
* @returns Promise with tokenized text and mapping
|
|
100
|
+
*/
|
|
101
|
+
async tokenize(text, config) {
|
|
102
|
+
return this.request("/tokenize", "POST", {
|
|
103
|
+
text,
|
|
104
|
+
...config
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Detokenize text by replacing tokens with original values
|
|
109
|
+
* @param text - Tokenized text
|
|
110
|
+
* @param mapping - Token mapping from tokenize response
|
|
111
|
+
* @returns Promise with original text
|
|
112
|
+
*/
|
|
113
|
+
async detokenize(text, mapping) {
|
|
114
|
+
return this.request("/detokenize", "POST", {
|
|
115
|
+
text,
|
|
116
|
+
mapping
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Redact (permanently remove) sensitive information from text
|
|
121
|
+
*
|
|
122
|
+
* WARNING: Redaction is irreversible - original data cannot be restored!
|
|
123
|
+
*
|
|
124
|
+
* @param text - Text to redact
|
|
125
|
+
* @param config - Optional configuration (masking_char, entities)
|
|
126
|
+
* @returns Promise with redacted text and detected entities
|
|
127
|
+
*/
|
|
128
|
+
async redact(text, config) {
|
|
129
|
+
return this.request("/redact", "POST", {
|
|
130
|
+
text,
|
|
131
|
+
...config
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Mask (partially hide) sensitive information from text
|
|
136
|
+
*
|
|
137
|
+
* @param text - Text to mask
|
|
138
|
+
* @param config - Optional configuration (chars_to_show, from_end, masking_char, entities)
|
|
139
|
+
* @returns Promise with masked text and detected entities
|
|
140
|
+
*/
|
|
141
|
+
async mask(text, config) {
|
|
142
|
+
return this.request("/mask", "POST", {
|
|
143
|
+
text,
|
|
144
|
+
...config
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Synthesize (replace real data with synthetic fake data)
|
|
149
|
+
*
|
|
150
|
+
* @param text - Text to synthesize
|
|
151
|
+
* @param config - Optional configuration (language, entities)
|
|
152
|
+
* @returns Promise with synthetic text and detected entities
|
|
153
|
+
*/
|
|
154
|
+
async synthesize(text, config) {
|
|
155
|
+
return this.request("/synthesize", "POST", {
|
|
156
|
+
text,
|
|
157
|
+
...config
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Hash (replace with deterministic hash values)
|
|
162
|
+
*
|
|
163
|
+
* @param text - Text to hash
|
|
164
|
+
* @param config - Optional configuration (hash_type, hash_prefix, hash_length, entities)
|
|
165
|
+
* @returns Promise with hashed text and detected entities
|
|
166
|
+
*/
|
|
167
|
+
async hash(text, config) {
|
|
168
|
+
return this.request("/hash", "POST", {
|
|
169
|
+
text,
|
|
170
|
+
...config
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Encrypt (reversibly protect) sensitive data in text using AES encryption
|
|
175
|
+
*
|
|
176
|
+
* @param text - Text to encrypt
|
|
177
|
+
* @param config - Optional configuration (encryption_key, entities)
|
|
178
|
+
* @returns Promise with encrypted text and detected entities
|
|
179
|
+
*/
|
|
180
|
+
async encrypt(text, config) {
|
|
181
|
+
return this.request("/encrypt", "POST", {
|
|
182
|
+
text,
|
|
183
|
+
...config
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export { APIError, AuthenticationError, Blindfold, BlindfoldError, NetworkError };
|
|
189
|
+
//# sourceMappingURL=index.mjs.map
|
|
190
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Base error class for Blindfold SDK\n */\nexport class BlindfoldError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'BlindfoldError'\n Object.setPrototypeOf(this, BlindfoldError.prototype)\n }\n}\n\n/**\n * Error thrown when authentication fails\n */\nexport class AuthenticationError extends BlindfoldError {\n constructor(message: string = 'Authentication failed. Please check your API key.') {\n super(message)\n this.name = 'AuthenticationError'\n Object.setPrototypeOf(this, AuthenticationError.prototype)\n }\n}\n\n/**\n * Error thrown when API request fails\n */\nexport class APIError extends BlindfoldError {\n statusCode: number\n responseBody?: any\n\n constructor(message: string, statusCode: number, responseBody?: any) {\n super(message)\n this.name = 'APIError'\n this.statusCode = statusCode\n this.responseBody = responseBody\n Object.setPrototypeOf(this, APIError.prototype)\n }\n}\n\n/**\n * Error thrown when network request fails\n */\nexport class NetworkError extends BlindfoldError {\n constructor(message: string = 'Network request failed. Please check your connection.') {\n super(message)\n this.name = 'NetworkError'\n Object.setPrototypeOf(this, NetworkError.prototype)\n }\n}\n","import type {\n BlindfoldConfig,\n TokenizeConfig,\n TokenizeResponse,\n DetokenizeResponse,\n RedactConfig,\n RedactResponse,\n MaskConfig,\n MaskResponse,\n SynthesizeConfig,\n SynthesizeResponse,\n HashConfig,\n HashResponse,\n EncryptConfig,\n EncryptResponse,\n APIErrorResponse,\n} from './types'\nimport { AuthenticationError, APIError, NetworkError } from './errors'\n\nconst DEFAULT_BASE_URL = 'https://api.blindfold.dev/api/public/v1'\n\n/**\n * Blindfold client for tokenization and detokenization\n */\nexport class Blindfold {\n private apiKey: string\n private baseUrl: string\n private userId?: string\n\n /**\n * Create a new Blindfold client\n * @param config - Configuration options\n */\n constructor(config: BlindfoldConfig) {\n this.apiKey = config.apiKey\n this.baseUrl = config.baseUrl || DEFAULT_BASE_URL\n this.userId = config.userId\n }\n\n /**\n * Make an authenticated request to the API\n */\n private async request<T>(\n endpoint: string,\n method: string,\n body?: any\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.apiKey,\n }\n\n if (this.userId) {\n headers['X-Blindfold-User-Id'] = this.userId\n }\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n })\n\n // Handle authentication errors\n if (response.status === 401 || response.status === 403) {\n throw new AuthenticationError(\n 'Authentication failed. Please check your API key.'\n )\n }\n\n // Handle other error responses\n if (!response.ok) {\n let errorMessage = `API request failed with status ${response.status}`\n let responseBody: any\n\n try {\n responseBody = await response.json()\n const errorData = responseBody as APIErrorResponse\n errorMessage = errorData.detail || errorData.message || errorMessage\n } catch {\n // If we can't parse the error response, use the status text\n errorMessage = `${errorMessage}: ${response.statusText}`\n }\n\n throw new APIError(errorMessage, response.status, responseBody)\n }\n\n return (await response.json()) as T\n } catch (error) {\n // Re-throw our custom errors\n if (\n error instanceof AuthenticationError ||\n error instanceof APIError\n ) {\n throw error\n }\n\n // Handle network errors\n if (error instanceof TypeError && error.message.includes('fetch')) {\n throw new NetworkError(\n 'Network request failed. Please check your connection and the API URL.'\n )\n }\n\n // Handle other errors\n throw new NetworkError(\n error instanceof Error ? error.message : 'Unknown error occurred'\n )\n }\n }\n\n /**\n * Tokenize text by replacing sensitive information with tokens\n * @param text - Text to tokenize\n * @param config - Optional configuration\n * @returns Promise with tokenized text and mapping\n */\n async tokenize(\n text: string,\n config?: TokenizeConfig\n ): Promise<TokenizeResponse> {\n return this.request<TokenizeResponse>('/tokenize', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detokenize text by replacing tokens with original values\n * @param text - Tokenized text\n * @param mapping - Token mapping from tokenize response\n * @returns Promise with original text\n */\n async detokenize(\n text: string,\n mapping: Record<string, string>\n ): Promise<DetokenizeResponse> {\n return this.request<DetokenizeResponse>('/detokenize', 'POST', {\n text,\n mapping,\n })\n }\n\n /**\n * Redact (permanently remove) sensitive information from text\n *\n * WARNING: Redaction is irreversible - original data cannot be restored!\n *\n * @param text - Text to redact\n * @param config - Optional configuration (masking_char, entities)\n * @returns Promise with redacted text and detected entities\n */\n async redact(\n text: string,\n config?: RedactConfig\n ): Promise<RedactResponse> {\n return this.request<RedactResponse>('/redact', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Mask (partially hide) sensitive information from text\n *\n * @param text - Text to mask\n * @param config - Optional configuration (chars_to_show, from_end, masking_char, entities)\n * @returns Promise with masked text and detected entities\n */\n async mask(\n text: string,\n config?: MaskConfig\n ): Promise<MaskResponse> {\n return this.request<MaskResponse>('/mask', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Synthesize (replace real data with synthetic fake data)\n *\n * @param text - Text to synthesize\n * @param config - Optional configuration (language, entities)\n * @returns Promise with synthetic text and detected entities\n */\n async synthesize(\n text: string,\n config?: SynthesizeConfig\n ): Promise<SynthesizeResponse> {\n return this.request<SynthesizeResponse>('/synthesize', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Hash (replace with deterministic hash values)\n *\n * @param text - Text to hash\n * @param config - Optional configuration (hash_type, hash_prefix, hash_length, entities)\n * @returns Promise with hashed text and detected entities\n */\n async hash(\n text: string,\n config?: HashConfig\n ): Promise<HashResponse> {\n return this.request<HashResponse>('/hash', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Encrypt (reversibly protect) sensitive data in text using AES encryption\n *\n * @param text - Text to encrypt\n * @param config - Optional configuration (encryption_key, entities)\n * @returns Promise with encrypted text and detected entities\n */\n async encrypt(\n text: string,\n config?: EncryptConfig\n ): Promise<EncryptResponse> {\n return this.request<EncryptResponse>('/encrypt', 'POST', {\n text,\n ...config,\n })\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blindfold/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "JavaScript/TypeScript SDK for Blindfold Gateway",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"type-check": "tsc --noEmit"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"blindfold",
|
|
25
|
+
"tokenization",
|
|
26
|
+
"pii",
|
|
27
|
+
"security"
|
|
28
|
+
],
|
|
29
|
+
"author": "",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^20.10.0",
|
|
33
|
+
"tsup": "^8.0.1",
|
|
34
|
+
"typescript": "^5.3.3"
|
|
35
|
+
}
|
|
36
|
+
}
|