@plyaz/types 1.10.0 → 1.11.1

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.
@@ -0,0 +1,397 @@
1
+ /**
2
+ * Service Layer Types for @plyaz/core
3
+ * Types specific to core package services
4
+ */
5
+ import type { ReactNode } from 'react';
6
+ import type { ApiClientOptions } from '../api/client';
7
+ /**
8
+ * Environment configuration for API client initialization
9
+ *
10
+ * Contains ONLY environment-level metadata used to determine configuration defaults.
11
+ * API-specific configuration (baseURL, encryption, timeout) should be passed separately
12
+ * via the `apiConfig` parameter when initializing the client.
13
+ *
14
+ * **Purpose**:
15
+ * - Determines which environment defaults to apply (production/staging/development)
16
+ * - Provides environment-specific metadata (API keys, rate limits)
17
+ * - Controls whether the client is set as the default for services/hooks
18
+ *
19
+ * **Configuration Merge Priority**:
20
+ * 1. Environment defaults (lowest priority) - from @plyaz/config based on `env`
21
+ * 2. Environment metadata (medium priority) - from this `envConfig` object
22
+ * 3. API configuration (highest priority) - from the separate `apiConfig` parameter
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // Basic usage - production with API key
27
+ * const envConfig: ApiEnvironmentConfig = {
28
+ * env: 'production',
29
+ * apiKey: process.env.API_KEY
30
+ * };
31
+ *
32
+ * await ApiClientService.init(envConfig, {
33
+ * baseURL: 'https://api.example.com',
34
+ * encryption: { key: encryptionKey }
35
+ * });
36
+ * ```
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // Multiple clients - main API set as default
41
+ * const mainEnv: ApiEnvironmentConfig = {
42
+ * env: 'production',
43
+ * setAsDefault: true // Services/hooks use this automatically
44
+ * };
45
+ *
46
+ * const analyticsEnv: ApiEnvironmentConfig = {
47
+ * env: 'production',
48
+ * setAsDefault: false // Must pass explicitly via ServiceOptions
49
+ * };
50
+ *
51
+ * const mainClient = await ApiClientService.init(mainEnv, mainConfig);
52
+ * const analyticsClient = await ApiClientService.init(analyticsEnv, analyticsConfig);
53
+ *
54
+ * // Use default client
55
+ * const campaigns = await fetchCampaigns({ page: 1 });
56
+ *
57
+ * // Use custom client via ServiceOptions
58
+ * const analytics = await fetchAnalytics(
59
+ * { date: '2025-10-16' },
60
+ * { apiClient: analyticsClient }
61
+ * );
62
+ * ```
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * // Development with rate limiting (reserved for future use)
67
+ * const envConfig: ApiEnvironmentConfig = {
68
+ * env: 'development',
69
+ * apiKey: 'dev-key',
70
+ * rateLimit: {
71
+ * maxRequests: 100,
72
+ * windowMs: 60000 // 1 minute
73
+ * }
74
+ * };
75
+ * ```
76
+ *
77
+ * @see ServiceOptions from @plyaz/types/api - For per-request configuration overrides
78
+ * @since 1.1.0
79
+ */
80
+ export interface ApiEnvironmentConfig {
81
+ /**
82
+ * Environment name - determines which default configuration to apply
83
+ *
84
+ * **Environment Defaults**:
85
+ * - `production`: Aggressive retries (5), encryption required, telemetry enabled
86
+ * - `staging`: Mirrors production for accurate testing
87
+ * - `development`: Conservative retries (1), encryption optional, full debug mode
88
+ * - `test`: Same as development
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * env: process.env.NODE_ENV as 'production'
93
+ * ```
94
+ */
95
+ env: 'development' | 'staging' | 'production' | 'test';
96
+ /**
97
+ * API authentication key for the environment
98
+ *
99
+ * When provided, automatically added to request headers as `X-API-Key`.
100
+ * Useful for API gateway authentication or environment-specific keys.
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * apiKey: process.env.NEXT_PUBLIC_API_KEY
105
+ * ```
106
+ *
107
+ * @optional
108
+ */
109
+ apiKey?: string;
110
+ /**
111
+ * Rate limiting configuration per environment
112
+ *
113
+ * **Note**: Currently reserved for future use. Rate limiting is typically
114
+ * handled at the server/API gateway level rather than the HTTP client.
115
+ * This field is preserved in the interface for future client-side rate
116
+ * limiting implementation if needed.
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * rateLimit: {
121
+ * maxRequests: 100, // Maximum requests per window
122
+ * windowMs: 60000 // Time window in milliseconds (1 minute)
123
+ * }
124
+ * ```
125
+ *
126
+ * @optional
127
+ * @future
128
+ */
129
+ rateLimit?: {
130
+ /** Maximum number of requests allowed within the time window */
131
+ maxRequests: number;
132
+ /** Time window in milliseconds for rate limiting */
133
+ windowMs: number;
134
+ };
135
+ /**
136
+ * Whether to set the created client as the default for @plyaz/api services and hooks
137
+ *
138
+ * **Default behavior**: `true` (if not specified)
139
+ *
140
+ * **When `true` (recommended for most apps)**:
141
+ * - Services and hooks from @plyaz/api automatically use this client
142
+ * - No need to pass `apiClient` in `ServiceOptions`
143
+ * - Simplifies usage across the entire application
144
+ *
145
+ * **When `false` (advanced use cases)**:
146
+ * - Client is NOT set as the default
147
+ * - Must explicitly pass client via `ServiceOptions.apiClient`
148
+ * - Useful for multiple API clients (main API, analytics API, etc.)
149
+ * - Useful for testing with mock clients
150
+ * - Useful for per-tenant API configurations
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * // Set as default (most common)
155
+ * await ApiClientService.init(
156
+ * { env: 'production', setAsDefault: true },
157
+ * apiConfig
158
+ * );
159
+ *
160
+ * // Now all services use this client automatically
161
+ * const campaigns = await fetchCampaigns({ page: 1 });
162
+ * ```
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * // Don't set as default (multiple clients)
167
+ * const analyticsClient = await ApiClientService.init(
168
+ * { env: 'production', setAsDefault: false },
169
+ * analyticsConfig
170
+ * );
171
+ *
172
+ * // Must pass client explicitly via ServiceOptions
173
+ * const analytics = await fetchAnalytics(
174
+ * { date: '2025-10-16' },
175
+ * { apiClient: analyticsClient }
176
+ * );
177
+ * ```
178
+ *
179
+ * @default true
180
+ * @optional
181
+ * @see ServiceOptions.apiClient from @plyaz/types/api - For passing custom client per request
182
+ */
183
+ setAsDefault?: boolean;
184
+ }
185
+ /**
186
+ * Props for ApiProvider component
187
+ *
188
+ * React provider component that initializes the API client service for React/Next.js applications.
189
+ * Wraps your app to ensure the API client is ready before rendering children.
190
+ *
191
+ * **Features**:
192
+ * - Automatic API client initialization on mount
193
+ * - Loading state management during initialization
194
+ * - Error handling with customizable error UI
195
+ * - Success/error callbacks for integration with state management
196
+ * - Singleton pattern - only initializes once per app lifecycle
197
+ *
198
+ * @example
199
+ * ```tsx
200
+ * // Basic usage in Next.js app layout
201
+ * import { ApiProvider } from '@plyaz/core';
202
+ *
203
+ * export default function RootLayout({ children }) {
204
+ * const envConfig = {
205
+ * env: process.env.NODE_ENV as 'production',
206
+ * apiKey: process.env.NEXT_PUBLIC_API_KEY,
207
+ * };
208
+ *
209
+ * const apiConfig = {
210
+ * baseURL: process.env.NEXT_PUBLIC_API_URL!,
211
+ * encryption: {
212
+ * key: {
213
+ * id: 'prod-key-v1',
214
+ * key: process.env.NEXT_PUBLIC_ENCRYPTION_KEY!,
215
+ * algorithm: 'AES-GCM',
216
+ * format: 'raw'
217
+ * }
218
+ * },
219
+ * };
220
+ *
221
+ * return (
222
+ * <ApiProvider envConfig={envConfig} apiConfig={apiConfig}>
223
+ * {children}
224
+ * </ApiProvider>
225
+ * );
226
+ * }
227
+ * ```
228
+ *
229
+ * @example
230
+ * ```tsx
231
+ * // With custom loading and error components
232
+ * <ApiProvider
233
+ * envConfig={envConfig}
234
+ * apiConfig={apiConfig}
235
+ * loadingComponent={
236
+ * <div className="loading">
237
+ * <Spinner />
238
+ * <p>Initializing API client...</p>
239
+ * </div>
240
+ * }
241
+ * errorComponent={(error) => (
242
+ * <div className="error">
243
+ * <h2>API Initialization Failed</h2>
244
+ * <p>{error.message}</p>
245
+ * <button onClick={() => window.location.reload()}>Retry</button>
246
+ * </div>
247
+ * )}
248
+ * onInitialized={() => {
249
+ * console.log('[App] API client ready');
250
+ * }}
251
+ * onError={(error) => {
252
+ * console.error('[App] API initialization error:', error);
253
+ * }}
254
+ * >
255
+ * {children}
256
+ * </ApiProvider>
257
+ * ```
258
+ *
259
+ * @example
260
+ * ```tsx
261
+ * // With state management integration
262
+ * <ApiProvider
263
+ * envConfig={envConfig}
264
+ * apiConfig={{
265
+ * ...apiConfig,
266
+ * clientEvents: {
267
+ * onRequestStart: (event) => {
268
+ * apiStore.setState({ loading: true, requestId: event.data.id });
269
+ * },
270
+ * onResponseReceived: (event) => {
271
+ * apiStore.setState({ loading: false, lastResponse: event.data });
272
+ * },
273
+ * },
274
+ * }}
275
+ * onInitialized={() => {
276
+ * appStore.setState({ apiReady: true });
277
+ * }}
278
+ * >
279
+ * {children}
280
+ * </ApiProvider>
281
+ * ```
282
+ *
283
+ * @see {@link ApiEnvironmentConfig} - Environment configuration options
284
+ * @see {@link ApiClientOptions} from @plyaz/types/api - Full API configuration options
285
+ * @since 1.1.0
286
+ */
287
+ export interface ApiProviderProps {
288
+ /**
289
+ * React children to render after successful initialization
290
+ *
291
+ * Children are only rendered once the API client is fully initialized and ready.
292
+ * If initialization fails, the error component is rendered instead.
293
+ */
294
+ children: ReactNode;
295
+ /**
296
+ * Environment configuration
297
+ *
298
+ * Contains environment-level metadata (env, apiKey, rateLimit, setAsDefault).
299
+ * Determines which default configuration to apply from @plyaz/config.
300
+ *
301
+ * @see {@link ApiEnvironmentConfig} - Full configuration options
302
+ */
303
+ envConfig: ApiEnvironmentConfig;
304
+ /**
305
+ * API configuration
306
+ *
307
+ * Contains API-specific settings (baseURL, encryption, timeout, event handlers).
308
+ * All options from @plyaz/api's `ApiClientOptions` interface are supported.
309
+ *
310
+ * **Required fields**:
311
+ * - `baseURL`: API base URL
312
+ *
313
+ * **Commonly configured**:
314
+ * - `encryption`: Encryption configuration with key
315
+ * - `timeout`: Request timeout in milliseconds
316
+ * - `clientEvents`: Event handlers for monitoring
317
+ * - `retry`: Retry strategy configuration
318
+ *
319
+ * @see {@link ApiClientOptions} from @plyaz/types/api - Complete options reference
320
+ */
321
+ apiConfig: Partial<ApiClientOptions>;
322
+ /**
323
+ * Loading component to show while initializing
324
+ *
325
+ * Rendered while the API client is being initialized. If not provided,
326
+ * a default loading message is shown.
327
+ *
328
+ * @optional
329
+ *
330
+ * @example
331
+ * ```tsx
332
+ * loadingComponent={
333
+ * <div className="loading">
334
+ * <Spinner size="large" />
335
+ * <p>Setting up API connection...</p>
336
+ * </div>
337
+ * }
338
+ * ```
339
+ */
340
+ loadingComponent?: ReactNode;
341
+ /**
342
+ * Error component to show if initialization fails
343
+ *
344
+ * Rendered when API client initialization fails. Receives the error as a parameter.
345
+ * If not provided, a default error message is shown.
346
+ *
347
+ * @optional
348
+ *
349
+ * @example
350
+ * ```tsx
351
+ * errorComponent={(error) => (
352
+ * <ErrorBoundary error={error}>
353
+ * <button onClick={() => window.location.reload()}>
354
+ * Retry
355
+ * </button>
356
+ * </ErrorBoundary>
357
+ * )}
358
+ * ```
359
+ */
360
+ errorComponent?: (error: Error) => ReactNode;
361
+ /**
362
+ * Callback when initialization completes successfully
363
+ *
364
+ * Called once the API client is fully initialized and ready to use.
365
+ * Useful for tracking initialization success or triggering post-init logic.
366
+ *
367
+ * @optional
368
+ *
369
+ * @example
370
+ * ```tsx
371
+ * onInitialized={() => {
372
+ * console.log('[App] API client initialized');
373
+ * analytics.track('api_client_ready');
374
+ * appStore.setState({ apiReady: true });
375
+ * }}
376
+ * ```
377
+ */
378
+ onInitialized?: () => void;
379
+ /**
380
+ * Callback when initialization fails
381
+ *
382
+ * Called if API client initialization throws an error.
383
+ * Useful for error tracking, logging, or showing user notifications.
384
+ *
385
+ * @optional
386
+ *
387
+ * @example
388
+ * ```tsx
389
+ * onError={(error) => {
390
+ * console.error('[App] API initialization failed:', error);
391
+ * Sentry.captureException(error);
392
+ * toast.error('Failed to connect to API');
393
+ * }}
394
+ * ```
395
+ */
396
+ onError?: (error: Error) => void;
397
+ }