@blindfold/sdk 1.1.0 → 1.3.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 +19 -0
- package/dist/index.d.mts +66 -2
- package/dist/index.d.ts +66 -2
- package/dist/index.js +98 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,6 +164,25 @@ const response = await client.encrypt(
|
|
|
164
164
|
);
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
+
## Batch Processing
|
|
168
|
+
|
|
169
|
+
Process multiple texts in a single request (max 100 texts):
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
const result = await client.tokenizeBatch(
|
|
173
|
+
["Contact John Doe", "jane@example.com", "No PII here"],
|
|
174
|
+
{ policy: "gdpr_eu" }
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
console.log(result.total); // 3
|
|
178
|
+
console.log(result.succeeded); // 3
|
|
179
|
+
console.log(result.failed); // 0
|
|
180
|
+
|
|
181
|
+
result.results.forEach(item => console.log(item.text));
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
All methods have batch variants: `tokenizeBatch`, `detectBatch`, `redactBatch`, `maskBatch`, `synthesizeBatch`, `hashBatch`, `encryptBatch`.
|
|
185
|
+
|
|
167
186
|
## Configuration
|
|
168
187
|
|
|
169
188
|
### Entity Types
|
package/dist/index.d.mts
CHANGED
|
@@ -6,6 +6,8 @@ interface BlindfoldConfig {
|
|
|
6
6
|
apiKey: string;
|
|
7
7
|
/** Base URL for the API (default: https://api.blindfold.dev/api/public/v1) */
|
|
8
8
|
baseUrl?: string;
|
|
9
|
+
/** Region for data residency ("eu" or "us"). Overrides baseUrl if baseUrl is not set. */
|
|
10
|
+
region?: 'eu' | 'us';
|
|
9
11
|
/** Optional user ID to track who is making the request */
|
|
10
12
|
userId?: string;
|
|
11
13
|
/** Maximum number of retries on transient errors (default: 2, 0 to disable) */
|
|
@@ -49,7 +51,7 @@ interface DetectResponse {
|
|
|
49
51
|
*/
|
|
50
52
|
interface DetectedEntity {
|
|
51
53
|
/** Entity type (e.g., "person", "email address", "phone number") */
|
|
52
|
-
|
|
54
|
+
type: string;
|
|
53
55
|
/** Original text of the entity */
|
|
54
56
|
text: string;
|
|
55
57
|
/** Start index in text */
|
|
@@ -209,6 +211,19 @@ interface EncryptResponse {
|
|
|
209
211
|
/** Number of entities encrypted */
|
|
210
212
|
entities_count: number;
|
|
211
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Response wrapper for batch processing
|
|
216
|
+
*/
|
|
217
|
+
interface BatchResponse {
|
|
218
|
+
/** Array of individual results (or { error: string } for failed items) */
|
|
219
|
+
results: (Record<string, unknown>)[];
|
|
220
|
+
/** Total number of texts submitted */
|
|
221
|
+
total: number;
|
|
222
|
+
/** Number of texts processed successfully */
|
|
223
|
+
succeeded: number;
|
|
224
|
+
/** Number of texts that failed processing */
|
|
225
|
+
failed: number;
|
|
226
|
+
}
|
|
212
227
|
/**
|
|
213
228
|
* Error response from API
|
|
214
229
|
*/
|
|
@@ -307,6 +322,55 @@ declare class Blindfold {
|
|
|
307
322
|
* @returns Promise with encrypted text and detected entities
|
|
308
323
|
*/
|
|
309
324
|
encrypt(text: string, config?: EncryptConfig): Promise<EncryptResponse>;
|
|
325
|
+
/**
|
|
326
|
+
* Tokenize multiple texts in a single request
|
|
327
|
+
* @param texts - Array of texts to tokenize (max 100)
|
|
328
|
+
* @param config - Optional configuration
|
|
329
|
+
* @returns Promise with batch results
|
|
330
|
+
*/
|
|
331
|
+
tokenizeBatch(texts: string[], config?: TokenizeConfig): Promise<BatchResponse>;
|
|
332
|
+
/**
|
|
333
|
+
* Detect PII in multiple texts in a single request
|
|
334
|
+
* @param texts - Array of texts to analyze (max 100)
|
|
335
|
+
* @param config - Optional configuration
|
|
336
|
+
* @returns Promise with batch results
|
|
337
|
+
*/
|
|
338
|
+
detectBatch(texts: string[], config?: DetectConfig): Promise<BatchResponse>;
|
|
339
|
+
/**
|
|
340
|
+
* Redact PII from multiple texts in a single request
|
|
341
|
+
* @param texts - Array of texts to redact (max 100)
|
|
342
|
+
* @param config - Optional configuration
|
|
343
|
+
* @returns Promise with batch results
|
|
344
|
+
*/
|
|
345
|
+
redactBatch(texts: string[], config?: RedactConfig): Promise<BatchResponse>;
|
|
346
|
+
/**
|
|
347
|
+
* Mask PII in multiple texts in a single request
|
|
348
|
+
* @param texts - Array of texts to mask (max 100)
|
|
349
|
+
* @param config - Optional configuration
|
|
350
|
+
* @returns Promise with batch results
|
|
351
|
+
*/
|
|
352
|
+
maskBatch(texts: string[], config?: MaskConfig): Promise<BatchResponse>;
|
|
353
|
+
/**
|
|
354
|
+
* Synthesize multiple texts in a single request
|
|
355
|
+
* @param texts - Array of texts to synthesize (max 100)
|
|
356
|
+
* @param config - Optional configuration
|
|
357
|
+
* @returns Promise with batch results
|
|
358
|
+
*/
|
|
359
|
+
synthesizeBatch(texts: string[], config?: SynthesizeConfig): Promise<BatchResponse>;
|
|
360
|
+
/**
|
|
361
|
+
* Hash PII in multiple texts in a single request
|
|
362
|
+
* @param texts - Array of texts to hash (max 100)
|
|
363
|
+
* @param config - Optional configuration
|
|
364
|
+
* @returns Promise with batch results
|
|
365
|
+
*/
|
|
366
|
+
hashBatch(texts: string[], config?: HashConfig): Promise<BatchResponse>;
|
|
367
|
+
/**
|
|
368
|
+
* Encrypt PII in multiple texts in a single request
|
|
369
|
+
* @param texts - Array of texts to encrypt (max 100)
|
|
370
|
+
* @param config - Optional configuration
|
|
371
|
+
* @returns Promise with batch results
|
|
372
|
+
*/
|
|
373
|
+
encryptBatch(texts: string[], config?: EncryptConfig): Promise<BatchResponse>;
|
|
310
374
|
}
|
|
311
375
|
|
|
312
376
|
/**
|
|
@@ -336,4 +400,4 @@ declare class NetworkError extends BlindfoldError {
|
|
|
336
400
|
constructor(message?: string);
|
|
337
401
|
}
|
|
338
402
|
|
|
339
|
-
export { APIError, type APIErrorResponse, AuthenticationError, Blindfold, type BlindfoldConfig, BlindfoldError, type DetectConfig, type DetectResponse, type DetectedEntity, type DetokenizeResponse, NetworkError, type TokenizeConfig, type TokenizeResponse };
|
|
403
|
+
export { APIError, type APIErrorResponse, AuthenticationError, type BatchResponse, Blindfold, type BlindfoldConfig, BlindfoldError, type DetectConfig, type DetectResponse, type DetectedEntity, type DetokenizeResponse, NetworkError, type TokenizeConfig, type TokenizeResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ interface BlindfoldConfig {
|
|
|
6
6
|
apiKey: string;
|
|
7
7
|
/** Base URL for the API (default: https://api.blindfold.dev/api/public/v1) */
|
|
8
8
|
baseUrl?: string;
|
|
9
|
+
/** Region for data residency ("eu" or "us"). Overrides baseUrl if baseUrl is not set. */
|
|
10
|
+
region?: 'eu' | 'us';
|
|
9
11
|
/** Optional user ID to track who is making the request */
|
|
10
12
|
userId?: string;
|
|
11
13
|
/** Maximum number of retries on transient errors (default: 2, 0 to disable) */
|
|
@@ -49,7 +51,7 @@ interface DetectResponse {
|
|
|
49
51
|
*/
|
|
50
52
|
interface DetectedEntity {
|
|
51
53
|
/** Entity type (e.g., "person", "email address", "phone number") */
|
|
52
|
-
|
|
54
|
+
type: string;
|
|
53
55
|
/** Original text of the entity */
|
|
54
56
|
text: string;
|
|
55
57
|
/** Start index in text */
|
|
@@ -209,6 +211,19 @@ interface EncryptResponse {
|
|
|
209
211
|
/** Number of entities encrypted */
|
|
210
212
|
entities_count: number;
|
|
211
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Response wrapper for batch processing
|
|
216
|
+
*/
|
|
217
|
+
interface BatchResponse {
|
|
218
|
+
/** Array of individual results (or { error: string } for failed items) */
|
|
219
|
+
results: (Record<string, unknown>)[];
|
|
220
|
+
/** Total number of texts submitted */
|
|
221
|
+
total: number;
|
|
222
|
+
/** Number of texts processed successfully */
|
|
223
|
+
succeeded: number;
|
|
224
|
+
/** Number of texts that failed processing */
|
|
225
|
+
failed: number;
|
|
226
|
+
}
|
|
212
227
|
/**
|
|
213
228
|
* Error response from API
|
|
214
229
|
*/
|
|
@@ -307,6 +322,55 @@ declare class Blindfold {
|
|
|
307
322
|
* @returns Promise with encrypted text and detected entities
|
|
308
323
|
*/
|
|
309
324
|
encrypt(text: string, config?: EncryptConfig): Promise<EncryptResponse>;
|
|
325
|
+
/**
|
|
326
|
+
* Tokenize multiple texts in a single request
|
|
327
|
+
* @param texts - Array of texts to tokenize (max 100)
|
|
328
|
+
* @param config - Optional configuration
|
|
329
|
+
* @returns Promise with batch results
|
|
330
|
+
*/
|
|
331
|
+
tokenizeBatch(texts: string[], config?: TokenizeConfig): Promise<BatchResponse>;
|
|
332
|
+
/**
|
|
333
|
+
* Detect PII in multiple texts in a single request
|
|
334
|
+
* @param texts - Array of texts to analyze (max 100)
|
|
335
|
+
* @param config - Optional configuration
|
|
336
|
+
* @returns Promise with batch results
|
|
337
|
+
*/
|
|
338
|
+
detectBatch(texts: string[], config?: DetectConfig): Promise<BatchResponse>;
|
|
339
|
+
/**
|
|
340
|
+
* Redact PII from multiple texts in a single request
|
|
341
|
+
* @param texts - Array of texts to redact (max 100)
|
|
342
|
+
* @param config - Optional configuration
|
|
343
|
+
* @returns Promise with batch results
|
|
344
|
+
*/
|
|
345
|
+
redactBatch(texts: string[], config?: RedactConfig): Promise<BatchResponse>;
|
|
346
|
+
/**
|
|
347
|
+
* Mask PII in multiple texts in a single request
|
|
348
|
+
* @param texts - Array of texts to mask (max 100)
|
|
349
|
+
* @param config - Optional configuration
|
|
350
|
+
* @returns Promise with batch results
|
|
351
|
+
*/
|
|
352
|
+
maskBatch(texts: string[], config?: MaskConfig): Promise<BatchResponse>;
|
|
353
|
+
/**
|
|
354
|
+
* Synthesize multiple texts in a single request
|
|
355
|
+
* @param texts - Array of texts to synthesize (max 100)
|
|
356
|
+
* @param config - Optional configuration
|
|
357
|
+
* @returns Promise with batch results
|
|
358
|
+
*/
|
|
359
|
+
synthesizeBatch(texts: string[], config?: SynthesizeConfig): Promise<BatchResponse>;
|
|
360
|
+
/**
|
|
361
|
+
* Hash PII in multiple texts in a single request
|
|
362
|
+
* @param texts - Array of texts to hash (max 100)
|
|
363
|
+
* @param config - Optional configuration
|
|
364
|
+
* @returns Promise with batch results
|
|
365
|
+
*/
|
|
366
|
+
hashBatch(texts: string[], config?: HashConfig): Promise<BatchResponse>;
|
|
367
|
+
/**
|
|
368
|
+
* Encrypt PII in multiple texts in a single request
|
|
369
|
+
* @param texts - Array of texts to encrypt (max 100)
|
|
370
|
+
* @param config - Optional configuration
|
|
371
|
+
* @returns Promise with batch results
|
|
372
|
+
*/
|
|
373
|
+
encryptBatch(texts: string[], config?: EncryptConfig): Promise<BatchResponse>;
|
|
310
374
|
}
|
|
311
375
|
|
|
312
376
|
/**
|
|
@@ -336,4 +400,4 @@ declare class NetworkError extends BlindfoldError {
|
|
|
336
400
|
constructor(message?: string);
|
|
337
401
|
}
|
|
338
402
|
|
|
339
|
-
export { APIError, type APIErrorResponse, AuthenticationError, Blindfold, type BlindfoldConfig, BlindfoldError, type DetectConfig, type DetectResponse, type DetectedEntity, type DetokenizeResponse, NetworkError, type TokenizeConfig, type TokenizeResponse };
|
|
403
|
+
export { APIError, type APIErrorResponse, AuthenticationError, type BatchResponse, Blindfold, type BlindfoldConfig, BlindfoldError, type DetectConfig, type DetectResponse, type DetectedEntity, type DetokenizeResponse, NetworkError, type TokenizeConfig, type TokenizeResponse };
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,10 @@ var NetworkError = class _NetworkError extends BlindfoldError {
|
|
|
35
35
|
// src/client.ts
|
|
36
36
|
var DEFAULT_BASE_URL = "https://api.blindfold.dev/api/public/v1";
|
|
37
37
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
38
|
+
var REGION_URLS = {
|
|
39
|
+
eu: "https://eu-api.blindfold.dev/api/public/v1",
|
|
40
|
+
us: "https://us-api.blindfold.dev/api/public/v1"
|
|
41
|
+
};
|
|
38
42
|
function sleep(ms) {
|
|
39
43
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
40
44
|
}
|
|
@@ -45,7 +49,15 @@ var Blindfold = class {
|
|
|
45
49
|
*/
|
|
46
50
|
constructor(config) {
|
|
47
51
|
this.apiKey = config.apiKey;
|
|
48
|
-
|
|
52
|
+
if (config.region && !config.baseUrl) {
|
|
53
|
+
const regionUrl = REGION_URLS[config.region];
|
|
54
|
+
if (!regionUrl) {
|
|
55
|
+
throw new Error(`Invalid region '${config.region}'. Must be one of: ${Object.keys(REGION_URLS).join(", ")}`);
|
|
56
|
+
}
|
|
57
|
+
this.baseUrl = regionUrl;
|
|
58
|
+
} else {
|
|
59
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
60
|
+
}
|
|
49
61
|
this.userId = config.userId;
|
|
50
62
|
this.maxRetries = config.maxRetries ?? 2;
|
|
51
63
|
this.retryDelay = config.retryDelay ?? 0.5;
|
|
@@ -254,6 +266,91 @@ var Blindfold = class {
|
|
|
254
266
|
...config
|
|
255
267
|
});
|
|
256
268
|
}
|
|
269
|
+
// ===== Batch methods =====
|
|
270
|
+
/**
|
|
271
|
+
* Tokenize multiple texts in a single request
|
|
272
|
+
* @param texts - Array of texts to tokenize (max 100)
|
|
273
|
+
* @param config - Optional configuration
|
|
274
|
+
* @returns Promise with batch results
|
|
275
|
+
*/
|
|
276
|
+
async tokenizeBatch(texts, config) {
|
|
277
|
+
return this.request("/tokenize", "POST", {
|
|
278
|
+
texts,
|
|
279
|
+
...config
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Detect PII in multiple texts in a single request
|
|
284
|
+
* @param texts - Array of texts to analyze (max 100)
|
|
285
|
+
* @param config - Optional configuration
|
|
286
|
+
* @returns Promise with batch results
|
|
287
|
+
*/
|
|
288
|
+
async detectBatch(texts, config) {
|
|
289
|
+
return this.request("/detect", "POST", {
|
|
290
|
+
texts,
|
|
291
|
+
...config
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Redact PII from multiple texts in a single request
|
|
296
|
+
* @param texts - Array of texts to redact (max 100)
|
|
297
|
+
* @param config - Optional configuration
|
|
298
|
+
* @returns Promise with batch results
|
|
299
|
+
*/
|
|
300
|
+
async redactBatch(texts, config) {
|
|
301
|
+
return this.request("/redact", "POST", {
|
|
302
|
+
texts,
|
|
303
|
+
...config
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Mask PII in multiple texts in a single request
|
|
308
|
+
* @param texts - Array of texts to mask (max 100)
|
|
309
|
+
* @param config - Optional configuration
|
|
310
|
+
* @returns Promise with batch results
|
|
311
|
+
*/
|
|
312
|
+
async maskBatch(texts, config) {
|
|
313
|
+
return this.request("/mask", "POST", {
|
|
314
|
+
texts,
|
|
315
|
+
...config
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Synthesize multiple texts in a single request
|
|
320
|
+
* @param texts - Array of texts to synthesize (max 100)
|
|
321
|
+
* @param config - Optional configuration
|
|
322
|
+
* @returns Promise with batch results
|
|
323
|
+
*/
|
|
324
|
+
async synthesizeBatch(texts, config) {
|
|
325
|
+
return this.request("/synthesize", "POST", {
|
|
326
|
+
texts,
|
|
327
|
+
...config
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Hash PII in multiple texts in a single request
|
|
332
|
+
* @param texts - Array of texts to hash (max 100)
|
|
333
|
+
* @param config - Optional configuration
|
|
334
|
+
* @returns Promise with batch results
|
|
335
|
+
*/
|
|
336
|
+
async hashBatch(texts, config) {
|
|
337
|
+
return this.request("/hash", "POST", {
|
|
338
|
+
texts,
|
|
339
|
+
...config
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Encrypt PII in multiple texts in a single request
|
|
344
|
+
* @param texts - Array of texts to encrypt (max 100)
|
|
345
|
+
* @param config - Optional configuration
|
|
346
|
+
* @returns Promise with batch results
|
|
347
|
+
*/
|
|
348
|
+
async encryptBatch(texts, config) {
|
|
349
|
+
return this.request("/encrypt", "POST", {
|
|
350
|
+
texts,
|
|
351
|
+
...config
|
|
352
|
+
});
|
|
353
|
+
}
|
|
257
354
|
};
|
|
258
355
|
|
|
259
356
|
exports.APIError = APIError;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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?: unknown\n\n constructor(message: string, statusCode: number, responseBody?: unknown) {\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 DetectConfig,\n DetectResponse,\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'\nconst RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504])\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\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 private maxRetries: number\n private retryDelay: number\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 this.maxRetries = config.maxRetries ?? 2\n this.retryDelay = config.retryDelay ?? 0.5\n }\n\n private retryWait(attempt: number, error?: APIError): number {\n if (error && error.statusCode === 429) {\n const body = error.responseBody as Record<string, unknown> | undefined\n if (body && typeof body.retry_after === 'number') {\n return body.retry_after * 1000\n }\n }\n const delay = this.retryDelay * (2 ** attempt) * 1000\n const jitter = delay * 0.1 * Math.random()\n return delay + jitter\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?: Record<string, unknown>\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 let lastError: Error = new NetworkError('Request failed')\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\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('Authentication failed. Please check your API key.')\n }\n\n // Handle other error responses\n if (!response.ok) {\n let errorMessage = `API request failed with status ${response.status}`\n let responseBody: unknown\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 // Never retry auth errors\n if (error instanceof AuthenticationError) {\n throw error\n }\n\n // Retry retryable API errors\n if (error instanceof APIError) {\n if (RETRYABLE_STATUS_CODES.has(error.statusCode) && attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt, error))\n continue\n }\n throw error\n }\n\n // Retry network errors\n if (error instanceof NetworkError) {\n lastError = error\n if (attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt))\n continue\n }\n throw error\n }\n\n // Handle raw fetch errors (network failures)\n if (error instanceof TypeError && error.message.includes('fetch')) {\n lastError = new NetworkError(\n 'Network request failed. Please check your connection and the API URL.'\n )\n if (attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt))\n continue\n }\n throw lastError\n }\n\n // Non-retryable unknown errors\n throw new NetworkError(error instanceof Error ? error.message : 'Unknown error occurred')\n }\n }\n\n throw lastError\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(text: string, config?: TokenizeConfig): Promise<TokenizeResponse> {\n return this.request<TokenizeResponse>('/tokenize', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detect PII in text without modifying it\n *\n * Returns only the detected entities with their types, positions,\n * and confidence scores. The original text is not transformed.\n *\n * @param text - Text to analyze for PII\n * @param config - Optional configuration (entities, score_threshold, policy)\n * @returns Promise with detected entities\n */\n async detect(text: string, config?: DetectConfig): Promise<DetectResponse> {\n return this.request<DetectResponse>('/detect', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detokenize text by replacing tokens with original values\n *\n * This method performs detokenization CLIENT-SIDE for better performance,\n * security, and to work offline. No API call is made.\n *\n * @param text - Tokenized text\n * @param mapping - Token mapping from tokenize response\n * @returns DetokenizeResponse with original text\n */\n detokenize(text: string, mapping: Record<string, string>): DetokenizeResponse {\n let result = text\n let replacements = 0\n\n // Sort tokens by length (longest first) to avoid partial replacements\n const sortedTokens = Object.keys(mapping).sort((a, b) => b.length - a.length)\n\n for (const token of sortedTokens) {\n const originalValue = mapping[token]\n const regex = new RegExp(token.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'g')\n const matches = result.match(regex)\n\n if (matches) {\n result = result.replace(regex, originalValue)\n replacements += matches.length\n }\n }\n\n return {\n text: result,\n replacements_made: replacements,\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(text: string, config?: RedactConfig): 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(text: string, config?: MaskConfig): 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(text: string, config?: SynthesizeConfig): 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(text: string, config?: HashConfig): 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(text: string, config?: EncryptConfig): Promise<EncryptResponse> {\n return this.request<EncryptResponse>('/encrypt', 'POST', {\n text,\n ...config,\n })\n }\n}\n"]}
|
|
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?: unknown\n\n constructor(message: string, statusCode: number, responseBody?: unknown) {\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 DetectConfig,\n DetectResponse,\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 BatchResponse,\n APIErrorResponse,\n} from './types'\nimport { AuthenticationError, APIError, NetworkError } from './errors'\n\nconst DEFAULT_BASE_URL = 'https://api.blindfold.dev/api/public/v1'\nconst RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504])\n\nconst REGION_URLS: Record<string, string> = {\n eu: 'https://eu-api.blindfold.dev/api/public/v1',\n us: 'https://us-api.blindfold.dev/api/public/v1',\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\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 private maxRetries: number\n private retryDelay: number\n\n /**\n * Create a new Blindfold client\n * @param config - Configuration options\n */\n constructor(config: BlindfoldConfig) {\n this.apiKey = config.apiKey\n if (config.region && !config.baseUrl) {\n const regionUrl = REGION_URLS[config.region]\n if (!regionUrl) {\n throw new Error(`Invalid region '${config.region}'. Must be one of: ${Object.keys(REGION_URLS).join(', ')}`)\n }\n this.baseUrl = regionUrl\n } else {\n this.baseUrl = config.baseUrl || DEFAULT_BASE_URL\n }\n this.userId = config.userId\n this.maxRetries = config.maxRetries ?? 2\n this.retryDelay = config.retryDelay ?? 0.5\n }\n\n private retryWait(attempt: number, error?: APIError): number {\n if (error && error.statusCode === 429) {\n const body = error.responseBody as Record<string, unknown> | undefined\n if (body && typeof body.retry_after === 'number') {\n return body.retry_after * 1000\n }\n }\n const delay = this.retryDelay * (2 ** attempt) * 1000\n const jitter = delay * 0.1 * Math.random()\n return delay + jitter\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?: Record<string, unknown>\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 let lastError: Error = new NetworkError('Request failed')\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\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('Authentication failed. Please check your API key.')\n }\n\n // Handle other error responses\n if (!response.ok) {\n let errorMessage = `API request failed with status ${response.status}`\n let responseBody: unknown\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 // Never retry auth errors\n if (error instanceof AuthenticationError) {\n throw error\n }\n\n // Retry retryable API errors\n if (error instanceof APIError) {\n if (RETRYABLE_STATUS_CODES.has(error.statusCode) && attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt, error))\n continue\n }\n throw error\n }\n\n // Retry network errors\n if (error instanceof NetworkError) {\n lastError = error\n if (attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt))\n continue\n }\n throw error\n }\n\n // Handle raw fetch errors (network failures)\n if (error instanceof TypeError && error.message.includes('fetch')) {\n lastError = new NetworkError(\n 'Network request failed. Please check your connection and the API URL.'\n )\n if (attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt))\n continue\n }\n throw lastError\n }\n\n // Non-retryable unknown errors\n throw new NetworkError(error instanceof Error ? error.message : 'Unknown error occurred')\n }\n }\n\n throw lastError\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(text: string, config?: TokenizeConfig): Promise<TokenizeResponse> {\n return this.request<TokenizeResponse>('/tokenize', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detect PII in text without modifying it\n *\n * Returns only the detected entities with their types, positions,\n * and confidence scores. The original text is not transformed.\n *\n * @param text - Text to analyze for PII\n * @param config - Optional configuration (entities, score_threshold, policy)\n * @returns Promise with detected entities\n */\n async detect(text: string, config?: DetectConfig): Promise<DetectResponse> {\n return this.request<DetectResponse>('/detect', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detokenize text by replacing tokens with original values\n *\n * This method performs detokenization CLIENT-SIDE for better performance,\n * security, and to work offline. No API call is made.\n *\n * @param text - Tokenized text\n * @param mapping - Token mapping from tokenize response\n * @returns DetokenizeResponse with original text\n */\n detokenize(text: string, mapping: Record<string, string>): DetokenizeResponse {\n let result = text\n let replacements = 0\n\n // Sort tokens by length (longest first) to avoid partial replacements\n const sortedTokens = Object.keys(mapping).sort((a, b) => b.length - a.length)\n\n for (const token of sortedTokens) {\n const originalValue = mapping[token]\n const regex = new RegExp(token.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'g')\n const matches = result.match(regex)\n\n if (matches) {\n result = result.replace(regex, originalValue)\n replacements += matches.length\n }\n }\n\n return {\n text: result,\n replacements_made: replacements,\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(text: string, config?: RedactConfig): 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(text: string, config?: MaskConfig): 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(text: string, config?: SynthesizeConfig): 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(text: string, config?: HashConfig): 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(text: string, config?: EncryptConfig): Promise<EncryptResponse> {\n return this.request<EncryptResponse>('/encrypt', 'POST', {\n text,\n ...config,\n })\n }\n\n // ===== Batch methods =====\n\n /**\n * Tokenize multiple texts in a single request\n * @param texts - Array of texts to tokenize (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async tokenizeBatch(texts: string[], config?: TokenizeConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/tokenize', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Detect PII in multiple texts in a single request\n * @param texts - Array of texts to analyze (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async detectBatch(texts: string[], config?: DetectConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/detect', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Redact PII from multiple texts in a single request\n * @param texts - Array of texts to redact (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async redactBatch(texts: string[], config?: RedactConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/redact', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Mask PII in multiple texts in a single request\n * @param texts - Array of texts to mask (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async maskBatch(texts: string[], config?: MaskConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/mask', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Synthesize multiple texts in a single request\n * @param texts - Array of texts to synthesize (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async synthesizeBatch(texts: string[], config?: SynthesizeConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/synthesize', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Hash PII in multiple texts in a single request\n * @param texts - Array of texts to hash (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async hashBatch(texts: string[], config?: HashConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/hash', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Encrypt PII in multiple texts in a single request\n * @param texts - Array of texts to encrypt (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async encryptBatch(texts: string[], config?: EncryptConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/encrypt', 'POST', {\n texts,\n ...config,\n })\n }\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -33,6 +33,10 @@ var NetworkError = class _NetworkError extends BlindfoldError {
|
|
|
33
33
|
// src/client.ts
|
|
34
34
|
var DEFAULT_BASE_URL = "https://api.blindfold.dev/api/public/v1";
|
|
35
35
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
36
|
+
var REGION_URLS = {
|
|
37
|
+
eu: "https://eu-api.blindfold.dev/api/public/v1",
|
|
38
|
+
us: "https://us-api.blindfold.dev/api/public/v1"
|
|
39
|
+
};
|
|
36
40
|
function sleep(ms) {
|
|
37
41
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
38
42
|
}
|
|
@@ -43,7 +47,15 @@ var Blindfold = class {
|
|
|
43
47
|
*/
|
|
44
48
|
constructor(config) {
|
|
45
49
|
this.apiKey = config.apiKey;
|
|
46
|
-
|
|
50
|
+
if (config.region && !config.baseUrl) {
|
|
51
|
+
const regionUrl = REGION_URLS[config.region];
|
|
52
|
+
if (!regionUrl) {
|
|
53
|
+
throw new Error(`Invalid region '${config.region}'. Must be one of: ${Object.keys(REGION_URLS).join(", ")}`);
|
|
54
|
+
}
|
|
55
|
+
this.baseUrl = regionUrl;
|
|
56
|
+
} else {
|
|
57
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
58
|
+
}
|
|
47
59
|
this.userId = config.userId;
|
|
48
60
|
this.maxRetries = config.maxRetries ?? 2;
|
|
49
61
|
this.retryDelay = config.retryDelay ?? 0.5;
|
|
@@ -252,6 +264,91 @@ var Blindfold = class {
|
|
|
252
264
|
...config
|
|
253
265
|
});
|
|
254
266
|
}
|
|
267
|
+
// ===== Batch methods =====
|
|
268
|
+
/**
|
|
269
|
+
* Tokenize multiple texts in a single request
|
|
270
|
+
* @param texts - Array of texts to tokenize (max 100)
|
|
271
|
+
* @param config - Optional configuration
|
|
272
|
+
* @returns Promise with batch results
|
|
273
|
+
*/
|
|
274
|
+
async tokenizeBatch(texts, config) {
|
|
275
|
+
return this.request("/tokenize", "POST", {
|
|
276
|
+
texts,
|
|
277
|
+
...config
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Detect PII in multiple texts in a single request
|
|
282
|
+
* @param texts - Array of texts to analyze (max 100)
|
|
283
|
+
* @param config - Optional configuration
|
|
284
|
+
* @returns Promise with batch results
|
|
285
|
+
*/
|
|
286
|
+
async detectBatch(texts, config) {
|
|
287
|
+
return this.request("/detect", "POST", {
|
|
288
|
+
texts,
|
|
289
|
+
...config
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Redact PII from multiple texts in a single request
|
|
294
|
+
* @param texts - Array of texts to redact (max 100)
|
|
295
|
+
* @param config - Optional configuration
|
|
296
|
+
* @returns Promise with batch results
|
|
297
|
+
*/
|
|
298
|
+
async redactBatch(texts, config) {
|
|
299
|
+
return this.request("/redact", "POST", {
|
|
300
|
+
texts,
|
|
301
|
+
...config
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Mask PII in multiple texts in a single request
|
|
306
|
+
* @param texts - Array of texts to mask (max 100)
|
|
307
|
+
* @param config - Optional configuration
|
|
308
|
+
* @returns Promise with batch results
|
|
309
|
+
*/
|
|
310
|
+
async maskBatch(texts, config) {
|
|
311
|
+
return this.request("/mask", "POST", {
|
|
312
|
+
texts,
|
|
313
|
+
...config
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Synthesize multiple texts in a single request
|
|
318
|
+
* @param texts - Array of texts to synthesize (max 100)
|
|
319
|
+
* @param config - Optional configuration
|
|
320
|
+
* @returns Promise with batch results
|
|
321
|
+
*/
|
|
322
|
+
async synthesizeBatch(texts, config) {
|
|
323
|
+
return this.request("/synthesize", "POST", {
|
|
324
|
+
texts,
|
|
325
|
+
...config
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Hash PII in multiple texts in a single request
|
|
330
|
+
* @param texts - Array of texts to hash (max 100)
|
|
331
|
+
* @param config - Optional configuration
|
|
332
|
+
* @returns Promise with batch results
|
|
333
|
+
*/
|
|
334
|
+
async hashBatch(texts, config) {
|
|
335
|
+
return this.request("/hash", "POST", {
|
|
336
|
+
texts,
|
|
337
|
+
...config
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Encrypt PII in multiple texts in a single request
|
|
342
|
+
* @param texts - Array of texts to encrypt (max 100)
|
|
343
|
+
* @param config - Optional configuration
|
|
344
|
+
* @returns Promise with batch results
|
|
345
|
+
*/
|
|
346
|
+
async encryptBatch(texts, config) {
|
|
347
|
+
return this.request("/encrypt", "POST", {
|
|
348
|
+
texts,
|
|
349
|
+
...config
|
|
350
|
+
});
|
|
351
|
+
}
|
|
255
352
|
};
|
|
256
353
|
|
|
257
354
|
export { APIError, AuthenticationError, Blindfold, BlindfoldError, NetworkError };
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +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?: unknown\n\n constructor(message: string, statusCode: number, responseBody?: unknown) {\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 DetectConfig,\n DetectResponse,\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'\nconst RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504])\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\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 private maxRetries: number\n private retryDelay: number\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 this.maxRetries = config.maxRetries ?? 2\n this.retryDelay = config.retryDelay ?? 0.5\n }\n\n private retryWait(attempt: number, error?: APIError): number {\n if (error && error.statusCode === 429) {\n const body = error.responseBody as Record<string, unknown> | undefined\n if (body && typeof body.retry_after === 'number') {\n return body.retry_after * 1000\n }\n }\n const delay = this.retryDelay * (2 ** attempt) * 1000\n const jitter = delay * 0.1 * Math.random()\n return delay + jitter\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?: Record<string, unknown>\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 let lastError: Error = new NetworkError('Request failed')\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\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('Authentication failed. Please check your API key.')\n }\n\n // Handle other error responses\n if (!response.ok) {\n let errorMessage = `API request failed with status ${response.status}`\n let responseBody: unknown\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 // Never retry auth errors\n if (error instanceof AuthenticationError) {\n throw error\n }\n\n // Retry retryable API errors\n if (error instanceof APIError) {\n if (RETRYABLE_STATUS_CODES.has(error.statusCode) && attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt, error))\n continue\n }\n throw error\n }\n\n // Retry network errors\n if (error instanceof NetworkError) {\n lastError = error\n if (attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt))\n continue\n }\n throw error\n }\n\n // Handle raw fetch errors (network failures)\n if (error instanceof TypeError && error.message.includes('fetch')) {\n lastError = new NetworkError(\n 'Network request failed. Please check your connection and the API URL.'\n )\n if (attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt))\n continue\n }\n throw lastError\n }\n\n // Non-retryable unknown errors\n throw new NetworkError(error instanceof Error ? error.message : 'Unknown error occurred')\n }\n }\n\n throw lastError\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(text: string, config?: TokenizeConfig): Promise<TokenizeResponse> {\n return this.request<TokenizeResponse>('/tokenize', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detect PII in text without modifying it\n *\n * Returns only the detected entities with their types, positions,\n * and confidence scores. The original text is not transformed.\n *\n * @param text - Text to analyze for PII\n * @param config - Optional configuration (entities, score_threshold, policy)\n * @returns Promise with detected entities\n */\n async detect(text: string, config?: DetectConfig): Promise<DetectResponse> {\n return this.request<DetectResponse>('/detect', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detokenize text by replacing tokens with original values\n *\n * This method performs detokenization CLIENT-SIDE for better performance,\n * security, and to work offline. No API call is made.\n *\n * @param text - Tokenized text\n * @param mapping - Token mapping from tokenize response\n * @returns DetokenizeResponse with original text\n */\n detokenize(text: string, mapping: Record<string, string>): DetokenizeResponse {\n let result = text\n let replacements = 0\n\n // Sort tokens by length (longest first) to avoid partial replacements\n const sortedTokens = Object.keys(mapping).sort((a, b) => b.length - a.length)\n\n for (const token of sortedTokens) {\n const originalValue = mapping[token]\n const regex = new RegExp(token.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'g')\n const matches = result.match(regex)\n\n if (matches) {\n result = result.replace(regex, originalValue)\n replacements += matches.length\n }\n }\n\n return {\n text: result,\n replacements_made: replacements,\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(text: string, config?: RedactConfig): 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(text: string, config?: MaskConfig): 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(text: string, config?: SynthesizeConfig): 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(text: string, config?: HashConfig): 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(text: string, config?: EncryptConfig): Promise<EncryptResponse> {\n return this.request<EncryptResponse>('/encrypt', 'POST', {\n text,\n ...config,\n })\n }\n}\n"]}
|
|
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?: unknown\n\n constructor(message: string, statusCode: number, responseBody?: unknown) {\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 DetectConfig,\n DetectResponse,\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 BatchResponse,\n APIErrorResponse,\n} from './types'\nimport { AuthenticationError, APIError, NetworkError } from './errors'\n\nconst DEFAULT_BASE_URL = 'https://api.blindfold.dev/api/public/v1'\nconst RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504])\n\nconst REGION_URLS: Record<string, string> = {\n eu: 'https://eu-api.blindfold.dev/api/public/v1',\n us: 'https://us-api.blindfold.dev/api/public/v1',\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\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 private maxRetries: number\n private retryDelay: number\n\n /**\n * Create a new Blindfold client\n * @param config - Configuration options\n */\n constructor(config: BlindfoldConfig) {\n this.apiKey = config.apiKey\n if (config.region && !config.baseUrl) {\n const regionUrl = REGION_URLS[config.region]\n if (!regionUrl) {\n throw new Error(`Invalid region '${config.region}'. Must be one of: ${Object.keys(REGION_URLS).join(', ')}`)\n }\n this.baseUrl = regionUrl\n } else {\n this.baseUrl = config.baseUrl || DEFAULT_BASE_URL\n }\n this.userId = config.userId\n this.maxRetries = config.maxRetries ?? 2\n this.retryDelay = config.retryDelay ?? 0.5\n }\n\n private retryWait(attempt: number, error?: APIError): number {\n if (error && error.statusCode === 429) {\n const body = error.responseBody as Record<string, unknown> | undefined\n if (body && typeof body.retry_after === 'number') {\n return body.retry_after * 1000\n }\n }\n const delay = this.retryDelay * (2 ** attempt) * 1000\n const jitter = delay * 0.1 * Math.random()\n return delay + jitter\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?: Record<string, unknown>\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 let lastError: Error = new NetworkError('Request failed')\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\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('Authentication failed. Please check your API key.')\n }\n\n // Handle other error responses\n if (!response.ok) {\n let errorMessage = `API request failed with status ${response.status}`\n let responseBody: unknown\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 // Never retry auth errors\n if (error instanceof AuthenticationError) {\n throw error\n }\n\n // Retry retryable API errors\n if (error instanceof APIError) {\n if (RETRYABLE_STATUS_CODES.has(error.statusCode) && attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt, error))\n continue\n }\n throw error\n }\n\n // Retry network errors\n if (error instanceof NetworkError) {\n lastError = error\n if (attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt))\n continue\n }\n throw error\n }\n\n // Handle raw fetch errors (network failures)\n if (error instanceof TypeError && error.message.includes('fetch')) {\n lastError = new NetworkError(\n 'Network request failed. Please check your connection and the API URL.'\n )\n if (attempt < this.maxRetries) {\n await sleep(this.retryWait(attempt))\n continue\n }\n throw lastError\n }\n\n // Non-retryable unknown errors\n throw new NetworkError(error instanceof Error ? error.message : 'Unknown error occurred')\n }\n }\n\n throw lastError\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(text: string, config?: TokenizeConfig): Promise<TokenizeResponse> {\n return this.request<TokenizeResponse>('/tokenize', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detect PII in text without modifying it\n *\n * Returns only the detected entities with their types, positions,\n * and confidence scores. The original text is not transformed.\n *\n * @param text - Text to analyze for PII\n * @param config - Optional configuration (entities, score_threshold, policy)\n * @returns Promise with detected entities\n */\n async detect(text: string, config?: DetectConfig): Promise<DetectResponse> {\n return this.request<DetectResponse>('/detect', 'POST', {\n text,\n ...config,\n })\n }\n\n /**\n * Detokenize text by replacing tokens with original values\n *\n * This method performs detokenization CLIENT-SIDE for better performance,\n * security, and to work offline. No API call is made.\n *\n * @param text - Tokenized text\n * @param mapping - Token mapping from tokenize response\n * @returns DetokenizeResponse with original text\n */\n detokenize(text: string, mapping: Record<string, string>): DetokenizeResponse {\n let result = text\n let replacements = 0\n\n // Sort tokens by length (longest first) to avoid partial replacements\n const sortedTokens = Object.keys(mapping).sort((a, b) => b.length - a.length)\n\n for (const token of sortedTokens) {\n const originalValue = mapping[token]\n const regex = new RegExp(token.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'g')\n const matches = result.match(regex)\n\n if (matches) {\n result = result.replace(regex, originalValue)\n replacements += matches.length\n }\n }\n\n return {\n text: result,\n replacements_made: replacements,\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(text: string, config?: RedactConfig): 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(text: string, config?: MaskConfig): 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(text: string, config?: SynthesizeConfig): 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(text: string, config?: HashConfig): 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(text: string, config?: EncryptConfig): Promise<EncryptResponse> {\n return this.request<EncryptResponse>('/encrypt', 'POST', {\n text,\n ...config,\n })\n }\n\n // ===== Batch methods =====\n\n /**\n * Tokenize multiple texts in a single request\n * @param texts - Array of texts to tokenize (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async tokenizeBatch(texts: string[], config?: TokenizeConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/tokenize', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Detect PII in multiple texts in a single request\n * @param texts - Array of texts to analyze (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async detectBatch(texts: string[], config?: DetectConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/detect', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Redact PII from multiple texts in a single request\n * @param texts - Array of texts to redact (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async redactBatch(texts: string[], config?: RedactConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/redact', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Mask PII in multiple texts in a single request\n * @param texts - Array of texts to mask (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async maskBatch(texts: string[], config?: MaskConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/mask', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Synthesize multiple texts in a single request\n * @param texts - Array of texts to synthesize (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async synthesizeBatch(texts: string[], config?: SynthesizeConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/synthesize', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Hash PII in multiple texts in a single request\n * @param texts - Array of texts to hash (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async hashBatch(texts: string[], config?: HashConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/hash', 'POST', {\n texts,\n ...config,\n })\n }\n\n /**\n * Encrypt PII in multiple texts in a single request\n * @param texts - Array of texts to encrypt (max 100)\n * @param config - Optional configuration\n * @returns Promise with batch results\n */\n async encryptBatch(texts: string[], config?: EncryptConfig): Promise<BatchResponse> {\n return this.request<BatchResponse>('/encrypt', 'POST', {\n texts,\n ...config,\n })\n }\n}\n"]}
|