@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 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
+ ```
@@ -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 };
@@ -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
+ }