@djangocfg/api 2.1.55 → 2.1.57

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.
Files changed (93) hide show
  1. package/dist/auth.cjs +28 -15
  2. package/dist/auth.cjs.map +1 -1
  3. package/dist/auth.d.cts +6 -6
  4. package/dist/auth.d.ts +6 -6
  5. package/dist/auth.mjs +28 -15
  6. package/dist/auth.mjs.map +1 -1
  7. package/dist/clients.cjs +56 -17
  8. package/dist/clients.cjs.map +1 -1
  9. package/dist/clients.d.cts +17 -17
  10. package/dist/clients.d.ts +17 -17
  11. package/dist/clients.mjs +56 -17
  12. package/dist/clients.mjs.map +1 -1
  13. package/dist/hooks.cjs +763 -12
  14. package/dist/hooks.cjs.map +1 -1
  15. package/dist/hooks.d.cts +11 -11
  16. package/dist/hooks.d.ts +11 -11
  17. package/dist/hooks.mjs +763 -12
  18. package/dist/hooks.mjs.map +1 -1
  19. package/dist/index.cjs +893 -69
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +59 -41
  22. package/dist/index.d.ts +59 -41
  23. package/dist/index.mjs +893 -69
  24. package/dist/index.mjs.map +1 -1
  25. package/package.json +3 -3
  26. package/src/generated/cfg_accounts/_utils/schemas/CentrifugoToken.schema.ts +1 -1
  27. package/src/generated/cfg_accounts/_utils/schemas/OAuthAuthorizeRequestRequest.schema.ts +2 -2
  28. package/src/generated/cfg_accounts/_utils/schemas/OAuthAuthorizeResponse.schema.ts +1 -1
  29. package/src/generated/cfg_accounts/_utils/schemas/OAuthCallbackRequestRequest.schema.ts +1 -1
  30. package/src/generated/cfg_accounts/_utils/schemas/OAuthConnection.schema.ts +1 -1
  31. package/src/generated/cfg_accounts/_utils/schemas/OAuthProvidersResponse.schema.ts +1 -1
  32. package/src/generated/cfg_accounts/_utils/schemas/OAuthTokenResponse.schema.ts +1 -1
  33. package/src/generated/cfg_accounts/_utils/schemas/OTPRequestRequest.schema.ts +1 -1
  34. package/src/generated/cfg_accounts/_utils/schemas/OTPVerifyRequest.schema.ts +1 -1
  35. package/src/generated/cfg_accounts/_utils/schemas/User.schema.ts +1 -1
  36. package/src/generated/cfg_accounts/api-instance.ts +61 -13
  37. package/src/generated/cfg_centrifugo/api-instance.ts +61 -13
  38. package/src/generated/cfg_totp/CLAUDE.md +90 -0
  39. package/src/generated/cfg_totp/_utils/fetchers/index.ts +33 -0
  40. package/src/generated/cfg_totp/_utils/fetchers/totp.ts +49 -0
  41. package/src/generated/cfg_totp/_utils/fetchers/totp__2fa_management.ts +108 -0
  42. package/src/generated/cfg_totp/_utils/fetchers/totp__2fa_setup.ts +153 -0
  43. package/src/generated/cfg_totp/_utils/fetchers/totp__2fa_verification.ts +152 -0
  44. package/src/generated/cfg_totp/_utils/fetchers/totp__backup_codes.ts +152 -0
  45. package/src/generated/cfg_totp/_utils/hooks/index.ts +33 -0
  46. package/src/generated/cfg_totp/_utils/hooks/totp.ts +42 -0
  47. package/src/generated/cfg_totp/_utils/hooks/totp__2fa_management.ts +58 -0
  48. package/src/generated/cfg_totp/_utils/hooks/totp__2fa_setup.ts +63 -0
  49. package/src/generated/cfg_totp/_utils/hooks/totp__2fa_verification.ts +62 -0
  50. package/src/generated/cfg_totp/_utils/hooks/totp__backup_codes.ts +59 -0
  51. package/src/generated/cfg_totp/_utils/schemas/BackupCodesRegenerateRequest.schema.ts +19 -0
  52. package/src/generated/cfg_totp/_utils/schemas/BackupCodesRegenerateResponse.schema.ts +20 -0
  53. package/src/generated/cfg_totp/_utils/schemas/BackupCodesStatus.schema.ts +21 -0
  54. package/src/generated/cfg_totp/_utils/schemas/ConfirmSetupRequest.schema.ts +20 -0
  55. package/src/generated/cfg_totp/_utils/schemas/ConfirmSetupResponse.schema.ts +21 -0
  56. package/src/generated/cfg_totp/_utils/schemas/DeviceList.schema.ts +26 -0
  57. package/src/generated/cfg_totp/_utils/schemas/DisableRequest.schema.ts +19 -0
  58. package/src/generated/cfg_totp/_utils/schemas/PaginatedDeviceListList.schema.ts +24 -0
  59. package/src/generated/cfg_totp/_utils/schemas/SetupRequest.schema.ts +19 -0
  60. package/src/generated/cfg_totp/_utils/schemas/SetupResponse.schema.ts +23 -0
  61. package/src/generated/cfg_totp/_utils/schemas/VerifyBackupRequest.schema.ts +20 -0
  62. package/src/generated/cfg_totp/_utils/schemas/VerifyRequest.schema.ts +20 -0
  63. package/src/generated/cfg_totp/_utils/schemas/VerifyResponse.schema.ts +24 -0
  64. package/src/generated/cfg_totp/_utils/schemas/index.ts +32 -0
  65. package/src/generated/cfg_totp/api-instance.ts +180 -0
  66. package/src/generated/cfg_totp/client.ts +313 -0
  67. package/src/generated/cfg_totp/enums.ts +12 -0
  68. package/src/generated/cfg_totp/errors.ts +117 -0
  69. package/src/generated/cfg_totp/http.ts +104 -0
  70. package/src/generated/cfg_totp/index.ts +302 -0
  71. package/src/generated/cfg_totp/logger.ts +260 -0
  72. package/src/generated/cfg_totp/retry.ts +176 -0
  73. package/src/generated/cfg_totp/schema.json +859 -0
  74. package/src/generated/cfg_totp/storage.ts +162 -0
  75. package/src/generated/cfg_totp/totp/client.ts +23 -0
  76. package/src/generated/cfg_totp/totp/index.ts +3 -0
  77. package/src/generated/cfg_totp/totp/models.ts +1 -0
  78. package/src/generated/cfg_totp/totp__2fa_management/client.ts +41 -0
  79. package/src/generated/cfg_totp/totp__2fa_management/index.ts +3 -0
  80. package/src/generated/cfg_totp/totp__2fa_management/models.ts +60 -0
  81. package/src/generated/cfg_totp/totp__2fa_setup/client.ts +32 -0
  82. package/src/generated/cfg_totp/totp__2fa_setup/index.ts +3 -0
  83. package/src/generated/cfg_totp/totp__2fa_setup/models.ts +54 -0
  84. package/src/generated/cfg_totp/totp__2fa_verification/client.ts +32 -0
  85. package/src/generated/cfg_totp/totp__2fa_verification/index.ts +3 -0
  86. package/src/generated/cfg_totp/totp__2fa_verification/models.ts +44 -0
  87. package/src/generated/cfg_totp/totp__backup_codes/client.ts +31 -0
  88. package/src/generated/cfg_totp/totp__backup_codes/index.ts +3 -0
  89. package/src/generated/cfg_totp/totp__backup_codes/models.ts +37 -0
  90. package/src/generated/cfg_totp/validation-events.ts +134 -0
  91. package/src/generated/cfg_webpush/_utils/schemas/SendPushRequestRequest.schema.ts +2 -2
  92. package/src/generated/cfg_webpush/_utils/schemas/SubscribeRequestRequest.schema.ts +1 -1
  93. package/src/generated/cfg_webpush/api-instance.ts +61 -13
@@ -0,0 +1,302 @@
1
+ // Auto-generated by DjangoCFG - see CLAUDE.md
2
+ /**
3
+ * Django CFG API - API Client with JWT Management
4
+ *
5
+ * Usage:
6
+ * ```typescript
7
+ * import { API } from './api';
8
+ *
9
+ * const api = new API('https://api.example.com');
10
+ *
11
+ * // Set JWT token
12
+ * api.setToken('your-jwt-token', 'refresh-token');
13
+ *
14
+ * // Use API
15
+ * const posts = await api.posts.list();
16
+ * const user = await api.users.retrieve(1);
17
+ *
18
+ * // Check authentication
19
+ * if (api.isAuthenticated()) {
20
+ * // ...
21
+ * }
22
+ *
23
+ * // Custom storage with logging (for Electron/Node.js)
24
+ * import { MemoryStorageAdapter, APILogger } from './storage';
25
+ * const logger = new APILogger({ enabled: true, logLevel: 'debug' });
26
+ * const api = new API('https://api.example.com', {
27
+ * storage: new MemoryStorageAdapter(logger),
28
+ * loggerConfig: { enabled: true, logLevel: 'debug' }
29
+ * });
30
+ *
31
+ * // Get OpenAPI schema
32
+ * const schema = api.getSchema();
33
+ * ```
34
+ */
35
+
36
+ import { APIClient } from "./client";
37
+ import {
38
+ StorageAdapter,
39
+ LocalStorageAdapter,
40
+ CookieStorageAdapter,
41
+ MemoryStorageAdapter
42
+ } from "./storage";
43
+ import type { RetryConfig } from "./retry";
44
+ import type { LoggerConfig } from "./logger";
45
+ import { APILogger } from "./logger";
46
+ import { 2faManagement } from "./totp__2fa_management/client";
47
+ import { 2faSetup } from "./totp__2fa_setup/client";
48
+ import { 2faVerification } from "./totp__2fa_verification/client";
49
+ import { BackupCodes } from "./totp__backup_codes/client";
50
+ import { Totp } from "./totp/client";
51
+ export * as 2faManagementTypes from "./totp__2fa_management/models";
52
+ // Note: Direct exports (export * from) are removed to avoid duplicate type conflicts
53
+ // Use namespace exports like CfgAccountsTypes.User or import from specific modules
54
+ export * as 2faSetupTypes from "./totp__2fa_setup/models";
55
+ // Note: Direct exports (export * from) are removed to avoid duplicate type conflicts
56
+ // Use namespace exports like CfgAccountsTypes.User or import from specific modules
57
+ export * as 2faVerificationTypes from "./totp__2fa_verification/models";
58
+ // Note: Direct exports (export * from) are removed to avoid duplicate type conflicts
59
+ // Use namespace exports like CfgAccountsTypes.User or import from specific modules
60
+ export * as BackupCodesTypes from "./totp__backup_codes/models";
61
+ // Note: Direct exports (export * from) are removed to avoid duplicate type conflicts
62
+ // Use namespace exports like CfgAccountsTypes.User or import from specific modules
63
+ export * as TotpTypes from "./totp/models";
64
+ // Note: Direct exports (export * from) are removed to avoid duplicate type conflicts
65
+ // Use namespace exports like CfgAccountsTypes.User or import from specific modules
66
+ export * as Enums from "./enums";
67
+
68
+ // Re-export Zod schemas for runtime validation
69
+ export * as Schemas from "./_utils/schemas";
70
+ // Also export all schemas directly for convenience
71
+ export * from "./_utils/schemas";
72
+
73
+ // Re-export Zod validation events for browser integration
74
+ export type { ValidationErrorDetail, ValidationErrorEvent } from "./validation-events";
75
+ export { dispatchValidationError, onValidationError, formatZodError } from "./validation-events";
76
+
77
+ // Re-export typed fetchers for universal usage
78
+ export * as Fetchers from "./_utils/fetchers";
79
+ export * from "./_utils/fetchers";
80
+
81
+ // Re-export API instance configuration functions
82
+ export {
83
+ configureAPI,
84
+ getAPIInstance,
85
+ reconfigureAPI,
86
+ clearAPITokens,
87
+ resetAPI,
88
+ isAPIConfigured
89
+ } from "./api-instance";
90
+ // NOTE: SWR hooks are generated in ./_utils/hooks/ but NOT exported here to keep
91
+ // the main bundle server-safe. Import hooks directly from the hooks directory:
92
+ // import { useUsers } from './_utils/hooks';
93
+ // Or use a separate entry point like '@djangocfg/api/hooks' for client components.
94
+
95
+ // Re-export core client
96
+ export { APIClient };
97
+
98
+ // Re-export storage adapters for convenience
99
+ export type { StorageAdapter };
100
+ export { LocalStorageAdapter, CookieStorageAdapter, MemoryStorageAdapter };
101
+
102
+ // Re-export error classes for convenience
103
+ export { APIError, NetworkError } from "./errors";
104
+
105
+ // Re-export HTTP adapters for custom implementations
106
+ export type { HttpClientAdapter, HttpRequest, HttpResponse } from "./http";
107
+ export { FetchAdapter } from "./http";
108
+
109
+ // Re-export logger types and classes
110
+ export type { LoggerConfig, RequestLog, ResponseLog, ErrorLog } from "./logger";
111
+ export { APILogger } from "./logger";
112
+
113
+ // Re-export retry configuration and utilities
114
+ export type { RetryConfig, FailedAttemptInfo } from "./retry";
115
+ export { withRetry, shouldRetry, DEFAULT_RETRY_CONFIG } from "./retry";
116
+
117
+ export const TOKEN_KEY = "auth_token";
118
+ export const REFRESH_TOKEN_KEY = "refresh_token";
119
+
120
+ export interface APIOptions {
121
+ /** Custom storage adapter (defaults to LocalStorageAdapter) */
122
+ storage?: StorageAdapter;
123
+ /** Retry configuration for failed requests */
124
+ retryConfig?: RetryConfig;
125
+ /** Logger configuration */
126
+ loggerConfig?: Partial<LoggerConfig>;
127
+ }
128
+
129
+ export class API {
130
+ private baseUrl: string;
131
+ private _client: APIClient;
132
+ private _token: string | null = null;
133
+ private _refreshToken: string | null = null;
134
+ private storage: StorageAdapter;
135
+ private options?: APIOptions;
136
+
137
+ // Sub-clients
138
+ public 2fa_management!: 2faManagement;
139
+ public 2fa_setup!: 2faSetup;
140
+ public 2fa_verification!: 2faVerification;
141
+ public backup_codes!: BackupCodes;
142
+ public totp!: Totp;
143
+
144
+ constructor(baseUrl: string, options?: APIOptions) {
145
+ this.baseUrl = baseUrl;
146
+ this.options = options;
147
+
148
+ // Create logger if config provided
149
+ const logger = options?.loggerConfig ? new APILogger(options.loggerConfig) : undefined;
150
+
151
+ // Initialize storage with logger
152
+ this.storage = options?.storage || new LocalStorageAdapter(logger);
153
+
154
+ this._loadTokensFromStorage();
155
+
156
+ // Initialize APIClient
157
+ this._client = new APIClient(this.baseUrl, {
158
+ retryConfig: this.options?.retryConfig,
159
+ loggerConfig: this.options?.loggerConfig,
160
+ });
161
+
162
+ // Always inject auth header wrapper (reads token dynamically from storage)
163
+ this._injectAuthHeader();
164
+
165
+ // Initialize sub-clients from APIClient
166
+ this.2fa_management = this._client.2fa_management;
167
+ this.2fa_setup = this._client.2fa_setup;
168
+ this.2fa_verification = this._client.2fa_verification;
169
+ this.backup_codes = this._client.backup_codes;
170
+ this.totp = this._client.totp;
171
+ }
172
+
173
+ private _loadTokensFromStorage(): void {
174
+ this._token = this.storage.getItem(TOKEN_KEY);
175
+ this._refreshToken = this.storage.getItem(REFRESH_TOKEN_KEY);
176
+ }
177
+
178
+ private _reinitClients(): void {
179
+ this._client = new APIClient(this.baseUrl, {
180
+ retryConfig: this.options?.retryConfig,
181
+ loggerConfig: this.options?.loggerConfig,
182
+ });
183
+
184
+ // Always inject auth header wrapper (reads token dynamically from storage)
185
+ this._injectAuthHeader();
186
+
187
+ // Reinitialize sub-clients
188
+ this.2fa_management = this._client.2fa_management;
189
+ this.2fa_setup = this._client.2fa_setup;
190
+ this.2fa_verification = this._client.2fa_verification;
191
+ this.backup_codes = this._client.backup_codes;
192
+ this.totp = this._client.totp;
193
+ }
194
+
195
+ private _injectAuthHeader(): void {
196
+ // Override request method to inject auth header
197
+ const originalRequest = this._client.request.bind(this._client);
198
+ this._client.request = async <T>(
199
+ method: string,
200
+ path: string,
201
+ options?: { params?: Record<string, any>; body?: any; formData?: FormData; headers?: Record<string, string> }
202
+ ): Promise<T> => {
203
+ // Read token from storage dynamically (supports JWT injection after instantiation)
204
+ const token = this.getToken();
205
+ const mergedOptions = {
206
+ ...options,
207
+ headers: {
208
+ ...(options?.headers || {}),
209
+ ...(token ? { 'Authorization': `Bearer ${token}` } : {}),
210
+ },
211
+ };
212
+
213
+ return originalRequest(method, path, mergedOptions);
214
+ };
215
+ }
216
+
217
+ /**
218
+ * Get current JWT token
219
+ */
220
+ getToken(): string | null {
221
+ return this.storage.getItem(TOKEN_KEY);
222
+ }
223
+
224
+ /**
225
+ * Get current refresh token
226
+ */
227
+ getRefreshToken(): string | null {
228
+ return this.storage.getItem(REFRESH_TOKEN_KEY);
229
+ }
230
+
231
+ /**
232
+ * Set JWT token and refresh token
233
+ * @param token - JWT access token
234
+ * @param refreshToken - JWT refresh token (optional)
235
+ */
236
+ setToken(token: string, refreshToken?: string): void {
237
+ this._token = token;
238
+ this.storage.setItem(TOKEN_KEY, token);
239
+
240
+ if (refreshToken) {
241
+ this._refreshToken = refreshToken;
242
+ this.storage.setItem(REFRESH_TOKEN_KEY, refreshToken);
243
+ }
244
+
245
+ // Reinitialize clients with new token
246
+ this._reinitClients();
247
+ }
248
+
249
+ /**
250
+ * Clear all tokens
251
+ */
252
+ clearTokens(): void {
253
+ this._token = null;
254
+ this._refreshToken = null;
255
+ this.storage.removeItem(TOKEN_KEY);
256
+ this.storage.removeItem(REFRESH_TOKEN_KEY);
257
+
258
+ // Reinitialize clients without token
259
+ this._reinitClients();
260
+ }
261
+
262
+ /**
263
+ * Check if user is authenticated
264
+ */
265
+ isAuthenticated(): boolean {
266
+ return !!this.getToken();
267
+ }
268
+
269
+ /**
270
+ * Update base URL and reinitialize clients
271
+ * @param url - New base URL
272
+ */
273
+ setBaseUrl(url: string): void {
274
+ this.baseUrl = url;
275
+ this._reinitClients();
276
+ }
277
+
278
+ /**
279
+ * Get current base URL
280
+ */
281
+ getBaseUrl(): string {
282
+ return this.baseUrl;
283
+ }
284
+
285
+ /**
286
+ * Get OpenAPI schema path
287
+ * @returns Path to the OpenAPI schema JSON file
288
+ *
289
+ * Note: The OpenAPI schema is available in the schema.json file.
290
+ * You can load it dynamically using:
291
+ * ```typescript
292
+ * const schema = await fetch('./schema.json').then(r => r.json());
293
+ * // or using fs in Node.js:
294
+ * // const schema = JSON.parse(fs.readFileSync('./schema.json', 'utf-8'));
295
+ * ```
296
+ */
297
+ getSchemaPath(): string {
298
+ return './schema.json';
299
+ }
300
+ }
301
+
302
+ export default API;
@@ -0,0 +1,260 @@
1
+ // Auto-generated by DjangoCFG - see CLAUDE.md
2
+ /**
3
+ * API Logger with Consola
4
+ * Beautiful console logging for API requests and responses
5
+ *
6
+ * Installation:
7
+ * npm install consola
8
+ */
9
+
10
+ import { type ConsolaInstance, createConsola } from 'consola';
11
+
12
+ /**
13
+ * Request log data
14
+ */
15
+ export interface RequestLog {
16
+ method: string;
17
+ url: string;
18
+ headers?: Record<string, string>;
19
+ body?: any;
20
+ timestamp: number;
21
+ }
22
+
23
+ /**
24
+ * Response log data
25
+ */
26
+ export interface ResponseLog {
27
+ status: number;
28
+ statusText: string;
29
+ data?: any;
30
+ duration: number;
31
+ timestamp: number;
32
+ }
33
+
34
+ /**
35
+ * Error log data
36
+ */
37
+ export interface ErrorLog {
38
+ message: string;
39
+ statusCode?: number;
40
+ fieldErrors?: Record<string, string[]>;
41
+ duration: number;
42
+ timestamp: number;
43
+ }
44
+
45
+ /**
46
+ * Logger configuration
47
+ */
48
+ export interface LoggerConfig {
49
+ /** Enable logging */
50
+ enabled: boolean;
51
+ /** Log requests */
52
+ logRequests: boolean;
53
+ /** Log responses */
54
+ logResponses: boolean;
55
+ /** Log errors */
56
+ logErrors: boolean;
57
+ /** Log request/response bodies */
58
+ logBodies: boolean;
59
+ /** Log headers (excluding sensitive ones) */
60
+ logHeaders: boolean;
61
+ /** Custom consola instance */
62
+ consola?: ConsolaInstance;
63
+ }
64
+
65
+ /**
66
+ * Default logger configuration
67
+ */
68
+ const DEFAULT_CONFIG: LoggerConfig = {
69
+ enabled: process.env.NODE_ENV !== 'production',
70
+ logRequests: true,
71
+ logResponses: true,
72
+ logErrors: true,
73
+ logBodies: true,
74
+ logHeaders: false,
75
+ };
76
+
77
+ /**
78
+ * Sensitive header names to filter out
79
+ */
80
+ const SENSITIVE_HEADERS = [
81
+ 'authorization',
82
+ 'cookie',
83
+ 'set-cookie',
84
+ 'x-api-key',
85
+ 'x-csrf-token',
86
+ ];
87
+
88
+ /**
89
+ * API Logger class
90
+ */
91
+ export class APILogger {
92
+ private config: LoggerConfig;
93
+ private consola: ConsolaInstance;
94
+
95
+ constructor(config: Partial<LoggerConfig> = {}) {
96
+ this.config = { ...DEFAULT_CONFIG, ...config };
97
+ this.consola = config.consola || createConsola({
98
+ level: this.config.enabled ? 4 : 0,
99
+ });
100
+ }
101
+
102
+ /**
103
+ * Enable logging
104
+ */
105
+ enable(): void {
106
+ this.config.enabled = true;
107
+ }
108
+
109
+ /**
110
+ * Disable logging
111
+ */
112
+ disable(): void {
113
+ this.config.enabled = false;
114
+ }
115
+
116
+ /**
117
+ * Update configuration
118
+ */
119
+ setConfig(config: Partial<LoggerConfig>): void {
120
+ this.config = { ...this.config, ...config };
121
+ }
122
+
123
+ /**
124
+ * Filter sensitive headers
125
+ */
126
+ private filterHeaders(headers?: Record<string, string>): Record<string, string> {
127
+ if (!headers) return {};
128
+
129
+ const filtered: Record<string, string> = {};
130
+ Object.keys(headers).forEach((key) => {
131
+ const lowerKey = key.toLowerCase();
132
+ if (SENSITIVE_HEADERS.includes(lowerKey)) {
133
+ filtered[key] = '***';
134
+ } else {
135
+ filtered[key] = headers[key] || '';
136
+ }
137
+ });
138
+
139
+ return filtered;
140
+ }
141
+
142
+ /**
143
+ * Log request
144
+ */
145
+ logRequest(request: RequestLog): void {
146
+ if (!this.config.enabled || !this.config.logRequests) return;
147
+
148
+ const { method, url, headers, body } = request;
149
+
150
+ this.consola.start(`${method} ${url}`);
151
+
152
+ if (this.config.logHeaders && headers) {
153
+ this.consola.debug('Headers:', this.filterHeaders(headers));
154
+ }
155
+
156
+ if (this.config.logBodies && body) {
157
+ this.consola.debug('Body:', body);
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Log response
163
+ */
164
+ logResponse(request: RequestLog, response: ResponseLog): void {
165
+ if (!this.config.enabled || !this.config.logResponses) return;
166
+
167
+ const { method, url } = request;
168
+ const { status, statusText, data, duration } = response;
169
+
170
+ const statusColor = status >= 500 ? 'red'
171
+ : status >= 400 ? 'yellow'
172
+ : status >= 300 ? 'cyan'
173
+ : 'green';
174
+
175
+ this.consola.success(
176
+ `${method} ${url} ${status} ${statusText} (${duration}ms)`
177
+ );
178
+
179
+ if (this.config.logBodies && data) {
180
+ this.consola.debug('Response:', data);
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Log error
186
+ */
187
+ logError(request: RequestLog, error: ErrorLog): void {
188
+ if (!this.config.enabled || !this.config.logErrors) return;
189
+
190
+ const { method, url } = request;
191
+ const { message, statusCode, fieldErrors, duration } = error;
192
+
193
+ this.consola.error(
194
+ `${method} ${url} ${statusCode || 'Network'} Error (${duration}ms)`
195
+ );
196
+
197
+ this.consola.error('Message:', message);
198
+
199
+ if (fieldErrors && Object.keys(fieldErrors).length > 0) {
200
+ this.consola.error('Field Errors:');
201
+ Object.entries(fieldErrors).forEach(([field, errors]) => {
202
+ errors.forEach((err) => {
203
+ this.consola.error(` • ${field}: ${err}`);
204
+ });
205
+ });
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Log general info
211
+ */
212
+ info(message: string, ...args: any[]): void {
213
+ if (!this.config.enabled) return;
214
+ this.consola.info(message, ...args);
215
+ }
216
+
217
+ /**
218
+ * Log warning
219
+ */
220
+ warn(message: string, ...args: any[]): void {
221
+ if (!this.config.enabled) return;
222
+ this.consola.warn(message, ...args);
223
+ }
224
+
225
+ /**
226
+ * Log error
227
+ */
228
+ error(message: string, ...args: any[]): void {
229
+ if (!this.config.enabled) return;
230
+ this.consola.error(message, ...args);
231
+ }
232
+
233
+ /**
234
+ * Log debug
235
+ */
236
+ debug(message: string, ...args: any[]): void {
237
+ if (!this.config.enabled) return;
238
+ this.consola.debug(message, ...args);
239
+ }
240
+
241
+ /**
242
+ * Log success
243
+ */
244
+ success(message: string, ...args: any[]): void {
245
+ if (!this.config.enabled) return;
246
+ this.consola.success(message, ...args);
247
+ }
248
+
249
+ /**
250
+ * Create a sub-logger with prefix
251
+ */
252
+ withTag(tag: string): ConsolaInstance {
253
+ return this.consola.withTag(tag);
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Default logger instance
259
+ */
260
+ export const defaultLogger = new APILogger();