@plyaz/types 1.9.3 → 1.10.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.
@@ -16,6 +16,7 @@ import type { NETWORK_QUALITY } from '../network';
16
16
  import type { HeaderEventHandlers, NetworkEventHandlers, ConfigEventHandlers, ClientEventHandlers, CacheEventHandlers, PerformanceEventHandlers } from '../events';
17
17
  import type { ApiClientOptions } from '../client';
18
18
  import type { DebugEventsConfig } from '../debugger';
19
+ import type { EncryptionConfig } from '../encryption';
19
20
  /**
20
21
  * HTTP Methods - extend from fetchff but uppercase
21
22
  */
@@ -246,6 +247,61 @@ export interface ApiConfig extends Partial<Omit<FetchffRequestConfig, 'retry' |
246
247
  * ```
247
248
  */
248
249
  enrichedHeaders?: EnrichedHeadersOptions;
250
+ /**
251
+ * Request/response encryption configuration for sensitive data
252
+ * Automatically encrypts specified fields in body, query params, or headers
253
+ * Supports AES-GCM, AES-CBC, and ChaCha20-Poly1305 algorithms
254
+ *
255
+ * **Primary Use Case: Per-Request via serviceOptions**
256
+ * ```typescript
257
+ * // In hooks/services - most common pattern
258
+ * const { data } = useCampaigns(
259
+ * ['campaigns'],
260
+ * { status: 'active' },
261
+ * {
262
+ * apiConfig: {
263
+ * encryption: {
264
+ * enabled: true,
265
+ * fields: ['participants.*.email', 'rewards.*.wallet'],
266
+ * key: encryptionKey
267
+ * }
268
+ * }
269
+ * }
270
+ * );
271
+ *
272
+ * // Or in service functions
273
+ * const campaign = await fetchCampaign('id', {
274
+ * apiConfig: {
275
+ * encryption: {
276
+ * enabled: true,
277
+ * algorithm: 'AES-GCM',
278
+ * fields: ['user.ssn', 'payment.cardNumber'],
279
+ * target: ['body', 'query'],
280
+ * key: {
281
+ * id: 'prod-key-v1',
282
+ * key: await getEncryptionKey(),
283
+ * algorithm: 'AES-GCM'
284
+ * }
285
+ * }
286
+ * }
287
+ * });
288
+ * ```
289
+ *
290
+ * **Global Client Configuration (Less Common)**
291
+ * ```typescript
292
+ * const api = createApiClient({
293
+ * encryption: {
294
+ * enabled: true,
295
+ * fields: ['*.ssn', '*.cardNumber'], // All ssn/cardNumber fields
296
+ * key: () => getEncryptionKey(), // Dynamic key provider
297
+ * autoDecrypt: true
298
+ * }
299
+ * });
300
+ * ```
301
+ *
302
+ * @see EncryptionConfig for full configuration options
303
+ */
304
+ encryption?: EncryptionConfig;
249
305
  /**
250
306
  * Event handlers for header changes, conflicts, and overrides
251
307
  * Track all header modifications throughout the request lifecycle
@@ -82,6 +82,7 @@ export declare const DEBUGGER_CONFIG_SOURCES: {
82
82
  readonly USER_HEADERS: "userHeaders";
83
83
  readonly INTERCEPTOR: "interceptor";
84
84
  readonly CONTEXT_HEADERS: "contextHeaders";
85
+ readonly ENCRYPTION: "encryption";
85
86
  };
86
87
  /**
87
88
  * Debug history entry types
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Encryption Module
3
+ * Exports for encryption types and interfaces
4
+ */
5
+ export type * from './types';
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Encryption Types
3
+ * Types for automatic request/response encryption
4
+ */
5
+ /**
6
+ * Supported encryption algorithms
7
+ * Using Web Crypto API compatible algorithms
8
+ */
9
+ export type EncryptionAlgorithm = 'AES-GCM' | 'AES-CBC' | 'ChaCha20-Poly1305';
10
+ /**
11
+ * Key format for encryption
12
+ */
13
+ export type KeyFormat = 'raw' | 'jwk' | 'base64';
14
+ /**
15
+ * Encryption key configuration
16
+ */
17
+ export interface EncryptionKey {
18
+ /**
19
+ * Key identifier for key rotation
20
+ * Used to identify which key was used for encryption
21
+ */
22
+ id: string;
23
+ /**
24
+ * The encryption key
25
+ * Can be CryptoKey, base64 string, or JWK
26
+ */
27
+ key: CryptoKey | string | JsonWebKey;
28
+ /**
29
+ * Key format (defaults to 'raw' for strings)
30
+ */
31
+ format?: KeyFormat;
32
+ /**
33
+ * Algorithm this key is used for
34
+ */
35
+ algorithm: EncryptionAlgorithm;
36
+ }
37
+ /**
38
+ * Key provider function for dynamic key retrieval
39
+ * Useful for key rotation and multi-tenant scenarios
40
+ */
41
+ export type KeyProvider = (context?: EncryptionContext) => Promise<EncryptionKey> | EncryptionKey;
42
+ /**
43
+ * Context passed to key provider
44
+ */
45
+ export interface EncryptionContext {
46
+ /**
47
+ * Request URL (optional if not available)
48
+ */
49
+ url?: string;
50
+ /**
51
+ * HTTP method (optional if not available)
52
+ */
53
+ method?: string;
54
+ /**
55
+ * Tenant ID (for multi-tenant)
56
+ */
57
+ tenantId?: string;
58
+ /**
59
+ * User ID
60
+ */
61
+ userId?: string;
62
+ /**
63
+ * Custom metadata
64
+ */
65
+ metadata?: Record<string, unknown>;
66
+ }
67
+ /**
68
+ * Field path specification for nested objects
69
+ * Examples: 'user.ssn', 'payment.cardNumber', 'data.*.sensitive'
70
+ */
71
+ export type FieldPath = string;
72
+ /**
73
+ * Target for encryption (where to apply encryption)
74
+ */
75
+ export type EncryptionTarget = 'body' | 'params' | 'headers' | 'all';
76
+ /**
77
+ * Encrypted field metadata
78
+ */
79
+ export interface EncryptedFieldMetadata {
80
+ /**
81
+ * Indicates this field is encrypted
82
+ */
83
+ encrypted: true;
84
+ /**
85
+ * Algorithm used
86
+ */
87
+ algorithm: EncryptionAlgorithm;
88
+ /**
89
+ * Key ID used for encryption (for key rotation)
90
+ */
91
+ keyId: string;
92
+ /**
93
+ * Initialization vector (base64)
94
+ */
95
+ iv: string;
96
+ /**
97
+ * Encrypted value (base64)
98
+ */
99
+ value: string;
100
+ /**
101
+ * Optional auth tag for authenticated encryption (base64)
102
+ */
103
+ authTag?: string;
104
+ }
105
+ /**
106
+ * Encryption configuration for API requests
107
+ */
108
+ export interface EncryptionConfig {
109
+ /**
110
+ * Enable encryption
111
+ */
112
+ enabled: boolean;
113
+ /**
114
+ * Encryption algorithm to use
115
+ * @default 'AES-GCM'
116
+ */
117
+ algorithm?: EncryptionAlgorithm;
118
+ /**
119
+ * Encryption key or key provider
120
+ * For key rotation, use KeyProvider function
121
+ */
122
+ key: EncryptionKey | KeyProvider;
123
+ /**
124
+ * Fields to encrypt (supports dot notation for nested fields)
125
+ * Examples:
126
+ * - ['ssn', 'cardNumber'] - encrypts these fields in body
127
+ * - ['user.password', 'data.sensitive'] - nested fields
128
+ * - ['*.ssn'] - all ssn fields at any level
129
+ *
130
+ * If not specified, encrypts entire payload
131
+ */
132
+ fields?: FieldPath[];
133
+ /**
134
+ * Where to apply encryption
135
+ * @default 'body'
136
+ */
137
+ target?: EncryptionTarget | EncryptionTarget[];
138
+ /**
139
+ * Automatically decrypt responses
140
+ * Looks for fields with EncryptedFieldMetadata structure
141
+ * @default true
142
+ */
143
+ autoDecrypt?: boolean;
144
+ /**
145
+ * Include metadata in encrypted fields
146
+ * If true, replaces field value with EncryptedFieldMetadata object
147
+ * If false, replaces with encrypted string only
148
+ * @default true
149
+ */
150
+ includeMetadata?: boolean;
151
+ /**
152
+ * Skip encryption for specific fields
153
+ * Useful when encrypting 'all' but want to exclude some fields
154
+ */
155
+ excludeFields?: FieldPath[];
156
+ /**
157
+ * Custom encryption function
158
+ * Override default encryption logic
159
+ */
160
+ encrypt?: (data: unknown, key: EncryptionKey, context?: EncryptionContext) => Promise<string | EncryptedFieldMetadata>;
161
+ /**
162
+ * Custom decryption function
163
+ * Override default decryption logic
164
+ */
165
+ decrypt?: (encrypted: string | EncryptedFieldMetadata, key: EncryptionKey, context?: EncryptionContext) => Promise<unknown>;
166
+ /**
167
+ * Error handling strategy
168
+ * - 'throw': Throw error on encryption failure
169
+ * - 'skip': Skip encryption on error, send plain data
170
+ * - 'placeholder': Replace with placeholder on error
171
+ * @default 'throw'
172
+ */
173
+ onError?: 'throw' | 'skip' | 'placeholder';
174
+ /**
175
+ * Placeholder value when onError is 'placeholder'
176
+ * @default '[ENCRYPTION_FAILED]'
177
+ */
178
+ errorPlaceholder?: string;
179
+ }
180
+ /**
181
+ * Encryption statistics and metrics
182
+ */
183
+ export interface EncryptionMetrics {
184
+ /**
185
+ * Total fields encrypted
186
+ */
187
+ fieldsEncrypted: number;
188
+ /**
189
+ * Total fields decrypted
190
+ */
191
+ fieldsDecrypted: number;
192
+ /**
193
+ * Encryption time in milliseconds
194
+ */
195
+ encryptionTime: number;
196
+ /**
197
+ * Decryption time in milliseconds
198
+ */
199
+ decryptionTime: number;
200
+ /**
201
+ * Key ID used
202
+ */
203
+ keyId: string;
204
+ /**
205
+ * Algorithm used
206
+ */
207
+ algorithm: EncryptionAlgorithm;
208
+ /**
209
+ * Errors encountered
210
+ */
211
+ errors: Array<{
212
+ field: string;
213
+ error: string;
214
+ }>;
215
+ }
216
+ /**
217
+ * Result of encryption operation
218
+ */
219
+ export interface EncryptionResult<T = unknown> {
220
+ /**
221
+ * Encrypted data
222
+ */
223
+ data: T;
224
+ /**
225
+ * Encryption metrics
226
+ */
227
+ metrics: EncryptionMetrics;
228
+ /**
229
+ * Original data (for debugging, only in dev mode)
230
+ */
231
+ original?: T;
232
+ }
@@ -876,7 +876,8 @@ var DEBUGGER_CONFIG_SOURCES = {
876
876
  ENRICHED_HEADERS: "enrichedHeaders",
877
877
  USER_HEADERS: "userHeaders",
878
878
  INTERCEPTOR: "interceptor",
879
- CONTEXT_HEADERS: "contextHeaders"
879
+ CONTEXT_HEADERS: "contextHeaders",
880
+ ENCRYPTION: "encryption"
880
881
  };
881
882
  var HISTORY_TYPES = {
882
883
  CONFIG: "config",