@djangocfg/monitor 2.1.322 → 2.1.331

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 (79) hide show
  1. package/dist/client.cjs +945 -1136
  2. package/dist/client.cjs.map +1 -1
  3. package/dist/client.d.cts +32 -46
  4. package/dist/client.d.ts +32 -46
  5. package/dist/client.mjs +945 -1147
  6. package/dist/client.mjs.map +1 -1
  7. package/dist/index.cjs +908 -1108
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.cts +32 -46
  10. package/dist/index.d.ts +32 -46
  11. package/dist/index.mjs +901 -1112
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/server.cjs +904 -1102
  14. package/dist/server.cjs.map +1 -1
  15. package/dist/server.d.cts +32 -46
  16. package/dist/server.d.ts +32 -46
  17. package/dist/server.mjs +896 -1105
  18. package/dist/server.mjs.map +1 -1
  19. package/package.json +7 -2
  20. package/src/_api/BaseClient.ts +1 -1
  21. package/src/_api/generated/_cfg_monitor/api.ts +120 -0
  22. package/src/_api/generated/_cfg_monitor/events.ts +198 -0
  23. package/src/_api/generated/_cfg_monitor/hooks/index.ts +4 -0
  24. package/src/_api/generated/_cfg_monitor/hooks/useCfgMonitorIngestCreate.ts +24 -0
  25. package/src/_api/generated/_cfg_monitor/index.ts +29 -0
  26. package/src/_api/generated/_cfg_monitor/schemas/EventTypeEnum.ts +9 -0
  27. package/src/_api/generated/_cfg_monitor/schemas/FrontendEventIngestRequest.ts +27 -0
  28. package/src/_api/generated/_cfg_monitor/schemas/IngestBatchRequest.ts +12 -0
  29. package/src/_api/generated/_cfg_monitor/schemas/LevelEnum.ts +9 -0
  30. package/src/_api/generated/_cfg_monitor/schemas/index.ts +7 -0
  31. package/src/_api/generated/_cfg_monitor/sdk.gen.ts +5 -0
  32. package/src/_api/generated/_cfg_monitor/types.gen.ts +5 -0
  33. package/src/_api/generated/client/client.gen.ts +280 -0
  34. package/src/_api/generated/client/index.ts +25 -0
  35. package/src/_api/generated/client/types.gen.ts +217 -0
  36. package/src/_api/generated/client/utils.gen.ts +318 -0
  37. package/src/_api/generated/client.gen.ts +16 -0
  38. package/src/_api/generated/core/auth.gen.ts +41 -0
  39. package/src/_api/generated/core/bodySerializer.gen.ts +82 -0
  40. package/src/_api/generated/core/params.gen.ts +169 -0
  41. package/src/_api/generated/core/pathSerializer.gen.ts +171 -0
  42. package/src/_api/generated/core/queryKeySerializer.gen.ts +117 -0
  43. package/src/_api/generated/core/serverSentEvents.gen.ts +242 -0
  44. package/src/_api/generated/core/types.gen.ts +104 -0
  45. package/src/_api/generated/core/utils.gen.ts +140 -0
  46. package/src/_api/generated/helpers/errors.ts +70 -0
  47. package/src/_api/generated/helpers/index.ts +25 -0
  48. package/src/_api/generated/helpers/logger.ts +123 -0
  49. package/src/_api/generated/helpers/storage.ts +83 -0
  50. package/src/_api/generated/helpers/validation-events.ts +52 -0
  51. package/src/_api/generated/index.ts +22 -0
  52. package/src/_api/generated/sdk.gen.ts +55 -0
  53. package/src/_api/generated/types.gen.ts +79 -0
  54. package/src/_api/index.ts +2 -2
  55. package/src/client/capture/console.ts +2 -3
  56. package/src/client/transport/ingest.ts +21 -17
  57. package/src/server/index.ts +3 -2
  58. package/src/_api/generated/cfg_monitor/CLAUDE.md +0 -60
  59. package/src/_api/generated/cfg_monitor/_utils/fetchers/index.ts +0 -30
  60. package/src/_api/generated/cfg_monitor/_utils/fetchers/monitor.ts +0 -51
  61. package/src/_api/generated/cfg_monitor/_utils/hooks/index.ts +0 -30
  62. package/src/_api/generated/cfg_monitor/_utils/hooks/monitor.ts +0 -43
  63. package/src/_api/generated/cfg_monitor/_utils/schemas/FrontendEventIngestRequest.schema.ts +0 -34
  64. package/src/_api/generated/cfg_monitor/_utils/schemas/IngestBatchRequest.schema.ts +0 -20
  65. package/src/_api/generated/cfg_monitor/_utils/schemas/index.ts +0 -22
  66. package/src/_api/generated/cfg_monitor/api-instance.ts +0 -181
  67. package/src/_api/generated/cfg_monitor/client.ts +0 -330
  68. package/src/_api/generated/cfg_monitor/enums.ts +0 -34
  69. package/src/_api/generated/cfg_monitor/errors.ts +0 -123
  70. package/src/_api/generated/cfg_monitor/http.ts +0 -160
  71. package/src/_api/generated/cfg_monitor/index.ts +0 -317
  72. package/src/_api/generated/cfg_monitor/logger.ts +0 -261
  73. package/src/_api/generated/cfg_monitor/monitor/client.ts +0 -26
  74. package/src/_api/generated/cfg_monitor/monitor/index.ts +0 -4
  75. package/src/_api/generated/cfg_monitor/monitor/models.ts +0 -47
  76. package/src/_api/generated/cfg_monitor/retry.ts +0 -177
  77. package/src/_api/generated/cfg_monitor/schema.json +0 -181
  78. package/src/_api/generated/cfg_monitor/storage.ts +0 -163
  79. package/src/_api/generated/cfg_monitor/validation-events.ts +0 -135
@@ -0,0 +1,79 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+
3
+ export type ClientOptions = {
4
+ baseUrl: 'http://localhost:8000' | (string & {});
5
+ };
6
+
7
+ /**
8
+ * * `JS_ERROR` - Js Error
9
+ * * `NETWORK_ERROR` - Network Error
10
+ * * `ERROR` - Error
11
+ * * `WARNING` - Warning
12
+ * * `PAGE_VIEW` - Page View
13
+ * * `PERFORMANCE` - Performance
14
+ * * `CONSOLE` - Console
15
+ */
16
+ export enum EventTypeEnum {
17
+ JS_ERROR = 'JS_ERROR',
18
+ NETWORK_ERROR = 'NETWORK_ERROR',
19
+ ERROR = 'ERROR',
20
+ WARNING = 'WARNING',
21
+ PAGE_VIEW = 'PAGE_VIEW',
22
+ PERFORMANCE = 'PERFORMANCE',
23
+ CONSOLE = 'CONSOLE'
24
+ }
25
+
26
+ /**
27
+ * Single browser event payload.
28
+ */
29
+ export type FrontendEventIngestRequest = {
30
+ build_id?: string;
31
+ environment?: string;
32
+ event_type: EventTypeEnum;
33
+ extra?: unknown;
34
+ fingerprint?: string;
35
+ http_method?: string;
36
+ http_status?: number | null;
37
+ http_url?: string;
38
+ level?: LevelEnum;
39
+ message: string;
40
+ project_name?: string;
41
+ session_id?: string;
42
+ stack_trace?: string;
43
+ url?: string;
44
+ user_agent?: string;
45
+ };
46
+
47
+ /**
48
+ * Batch of up to 50 browser events.
49
+ */
50
+ export type IngestBatchRequest = {
51
+ events: Array<FrontendEventIngestRequest>;
52
+ };
53
+
54
+ /**
55
+ * * `error` - Error
56
+ * * `warning` - Warning
57
+ * * `info` - Info
58
+ * * `debug` - Debug
59
+ */
60
+ export enum LevelEnum {
61
+ ERROR = 'error',
62
+ WARNING = 'warning',
63
+ INFO = 'info',
64
+ DEBUG = 'debug'
65
+ }
66
+
67
+ export type CfgMonitorIngestCreateData = {
68
+ body: IngestBatchRequest;
69
+ path?: never;
70
+ query?: never;
71
+ url: '/cfg/monitor/ingest/';
72
+ };
73
+
74
+ export type CfgMonitorIngestCreateResponses = {
75
+ /**
76
+ * Accepted
77
+ */
78
+ 202: unknown;
79
+ };
package/src/_api/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { monitorApi, configureMonitorApi, BaseClient } from './BaseClient'
2
- export type { FrontendEventIngestRequest, IngestBatchRequest } from './generated/cfg_monitor/monitor/models'
3
- export { FrontendEventIngestRequestEventType as EventType, FrontendEventIngestRequestLevel as EventLevel } from './generated/cfg_monitor/enums'
2
+ export type { FrontendEventIngestRequest, IngestBatchRequest } from './generated/_cfg_monitor/types.gen'
3
+ export { EventTypeEnum as EventType, LevelEnum as EventLevel } from './generated/_cfg_monitor/types.gen'
4
4
 
5
5
  /** Ingest path — matches the generated client. Single source of truth for sendBeacon fallback. */
6
6
  export const INGEST_PATH = '/cfg/monitor/ingest/'
@@ -3,15 +3,14 @@ import { getSessionId } from './session'
3
3
  import { monitorStore } from '../store'
4
4
  import { MONITOR_INGEST_PATTERN, DEFAULT_DEDUPE_TTL } from '../constants'
5
5
  import { EventType, EventLevel } from '../../_api'
6
- import type { FrontendEventIngestRequestEventType, FrontendEventIngestRequestLevel } from '../../_api/generated/cfg_monitor/enums'
7
6
 
8
7
  type ConsoleLevel = 'warn' | 'error'
9
8
 
10
- const levelMap: Record<ConsoleLevel, FrontendEventIngestRequestLevel> = {
9
+ const levelMap: Record<ConsoleLevel, EventLevel> = {
11
10
  warn: EventLevel.WARNING,
12
11
  error: EventLevel.ERROR,
13
12
  }
14
- const typeMap: Record<ConsoleLevel, FrontendEventIngestRequestEventType> = {
13
+ const typeMap: Record<ConsoleLevel, EventType> = {
15
14
  warn: EventType.WARNING,
16
15
  error: EventType.ERROR,
17
16
  }
@@ -1,27 +1,31 @@
1
- import { monitorApi } from '../../_api'
2
- import { API, MemoryStorageAdapter, KeepAliveFetchAdapter } from '../../_api/generated/cfg_monitor'
1
+ import { monitorApi, INGEST_PATH } from '../../_api'
2
+ import { Monitor } from '../../_api/generated/sdk.gen'
3
3
  import type { IngestBatchRequest } from '../../_api'
4
4
 
5
- /** Separate API instance with KeepAliveFetchAdapter — survives page unload */
6
- const monitorApiBeacon = new API('', {
7
- storage: new MemoryStorageAdapter(),
8
- httpClient: new KeepAliveFetchAdapter(),
9
- })
10
-
11
- export function syncBeaconBaseUrl(): void {
12
- monitorApiBeacon.setBaseUrl(monitorApi.getBaseUrl())
13
- }
14
-
5
+ /**
6
+ * Send a batch of events to the ingest endpoint.
7
+ *
8
+ * `useBeacon=true` is for page-unload scenarios — `fetch` with `keepalive: true`
9
+ * lets the request survive after the document goes away (browser-supported
10
+ * replacement for navigator.sendBeacon when we need JSON + custom headers).
11
+ */
15
12
  export async function sendBatch(
16
13
  batch: IngestBatchRequest,
17
14
  useBeacon = false,
18
15
  ): Promise<void> {
19
16
  if (batch.events.length === 0) return
20
17
 
21
- if (useBeacon) {
22
- syncBeaconBaseUrl()
23
- await monitorApiBeacon.monitor.ingestCreate(batch)
24
- } else {
25
- await monitorApi.monitor.ingestCreate(batch)
18
+ if (useBeacon && typeof fetch !== 'undefined') {
19
+ const baseUrl = monitorApi.getBaseUrl()
20
+ await fetch(`${baseUrl}${INGEST_PATH}`, {
21
+ method: 'POST',
22
+ headers: { 'Content-Type': 'application/json' },
23
+ body: JSON.stringify(batch),
24
+ keepalive: true,
25
+ credentials: 'include',
26
+ })
27
+ return
26
28
  }
29
+
30
+ await Monitor.cfgMonitorIngestCreate({ body: batch, throwOnError: true })
27
31
  }
@@ -22,7 +22,8 @@
22
22
  * ```
23
23
  */
24
24
 
25
- import { monitorApi, configureMonitorApi, EventType, EventLevel } from '../_api'
25
+ import { configureMonitorApi, EventType, EventLevel } from '../_api'
26
+ import { Monitor } from '../_api/generated/sdk.gen'
26
27
  import type { FrontendEventIngestRequest } from '../_api'
27
28
  import type { ServerMonitorConfig } from '../types'
28
29
 
@@ -34,7 +35,7 @@ let _config: ServerMonitorConfig = {}
34
35
  async function send(events: FrontendEventIngestRequest[]): Promise<void> {
35
36
  if (events.length === 0) return
36
37
  try {
37
- await monitorApi.monitor.ingestCreate({ events })
38
+ await Monitor.cfgMonitorIngestCreate({ body: { events }, throwOnError: true })
38
39
  } catch {
39
40
  // Never throw from monitor
40
41
  }
@@ -1,60 +0,0 @@
1
- # Django CFG API - Typescript Client
2
-
3
- Auto-generated. **Do not edit manually.**
4
-
5
- ```bash
6
- python manage.py generate_client --groups cfg_monitor --typescript
7
- ```
8
-
9
- ## Stats
10
-
11
- | | |
12
- |---|---|
13
- | Version | 3.1.0 |
14
- | Operations | 1 |
15
- | Schemas | 2 |
16
-
17
- ## Resources
18
-
19
- - **monitor** (1 ops)
20
-
21
- ## Operations
22
-
23
- **monitor:**
24
- - `POST` /cfg/monitor/ingest/ → `cfg_monitor_ingest_create`
25
-
26
- ## Usage
27
-
28
- ```typescript
29
- import { APIClient } from './';
30
-
31
- const client = new APIClient({ baseUrl, token });
32
-
33
- await client.monitor.create({ ... });
34
- ```
35
-
36
- **SWR Hooks:**
37
- ```typescript
38
- import { useMonitorList } from './hooks';
39
- const { data, isLoading } = useMonitorList();
40
- ```
41
-
42
- ## How It Works
43
-
44
- ```
45
- DRF ViewSets → drf-spectacular → OpenAPI → IR Parser → Generator → This Client
46
- ```
47
-
48
- **Configuration** (`api/config.py`):
49
- ```python
50
- openapi_client = OpenAPIClientConfig(
51
- enabled=True,
52
- groups=[OpenAPIGroupConfig(name="cfg_monitor", apps=["..."])],
53
- generate_zod_schemas=True, # → schemas.ts
54
- generate_fetchers=True, # → fetchers.ts
55
- generate_swr_hooks=True, # → hooks.ts
56
- )
57
- ```
58
-
59
- @see https://djangocfg.com/docs/features/api-generation
60
-
@@ -1,30 +0,0 @@
1
- // @ts-nocheck
2
- // Auto-generated by DjangoCFG - see CLAUDE.md
3
- /**
4
- * Typed Fetchers - Universal API functions
5
- *
6
- * Auto-generated from OpenAPI specification.
7
- * These functions work in any JavaScript environment.
8
- *
9
- * Features:
10
- * - Runtime validation with Zod
11
- * - Type-safe parameters and responses
12
- * - Works with any data-fetching library (SWR, React Query, etc)
13
- * - Server Component compatible
14
- *
15
- * Usage:
16
- * ```typescript
17
- * import * as fetchers from './fetchers'
18
- *
19
- * // Direct usage
20
- * const user = await fetchers.getUser(1)
21
- *
22
- * // With SWR
23
- * const { data } = useSWR('user-1', () => fetchers.getUser(1))
24
- *
25
- * // With React Query
26
- * const { data } = useQuery(['user', 1], () => fetchers.getUser(1))
27
- * ```
28
- */
29
-
30
- export * from './monitor'
@@ -1,51 +0,0 @@
1
- // @ts-nocheck
2
- // Auto-generated by DjangoCFG - see CLAUDE.md
3
- /**
4
- * Typed fetchers for Monitor
5
- *
6
- * Universal functions that work in any environment:
7
- * - Next.js (App Router / Pages Router / Server Components)
8
- * - React Native
9
- * - Node.js backend
10
- *
11
- * These fetchers use Zod schemas for runtime validation.
12
- *
13
- * Usage:
14
- * ```typescript
15
- * // Configure API once (in your app entry point)
16
- * import { configureAPI } from '../../api-instance'
17
- * configureAPI({ baseUrl: 'https://api.example.com' })
18
- *
19
- * // Then use fetchers anywhere
20
- * const users = await getUsers({ page: 1 })
21
- *
22
- * // With SWR
23
- * const { data } = useSWR(['users', params], () => getUsers(params))
24
- *
25
- * // With React Query
26
- * const { data } = useQuery(['users', params], () => getUsers(params))
27
- *
28
- * // In Server Component or SSR (pass custom client)
29
- * import { API } from '../../index'
30
- * const api = new API('https://api.example.com')
31
- * const users = await getUsers({ page: 1 }, api)
32
- * ```
33
- */
34
- import { consola } from 'consola'
35
- import { IngestBatchRequestSchema, type IngestBatchRequest } from '../schemas/IngestBatchRequest.schema'
36
- import { getAPIInstance } from '../../api-instance'
37
-
38
- /**
39
- * Ingest browser events
40
- *
41
- * @method POST
42
- * @path /cfg/monitor/ingest/
43
- */
44
- export async function createMonitorIngestCreate( data: IngestBatchRequest, client?: any
45
- ): Promise<any> {
46
- const api = client || getAPIInstance()
47
- const response = await api.monitor.ingestCreate(data)
48
- return response
49
- }
50
-
51
-
@@ -1,30 +0,0 @@
1
- // @ts-nocheck
2
- // Auto-generated by DjangoCFG - see CLAUDE.md
3
- 'use client';
4
-
5
- /**
6
- * SWR Hooks - React data fetching hooks
7
- *
8
- * Auto-generated from OpenAPI specification.
9
- * Powered by SWR for automatic caching and revalidation.
10
- *
11
- * Features:
12
- * - Automatic caching and deduplication
13
- * - Revalidation on focus/reconnect
14
- * - Optimistic updates
15
- * - Type-safe parameters and responses
16
- *
17
- * Usage:
18
- * ```typescript
19
- * import * as hooks from './hooks'
20
- *
21
- * // Query hooks (GET)
22
- * const { data, error, isLoading } = hooks.useUsers({ page: 1 })
23
- *
24
- * // Mutation hooks (POST/PUT/PATCH/DELETE)
25
- * const createUser = hooks.useCreateUser()
26
- * await createUser({ name: 'John' })
27
- * ```
28
- */
29
-
30
- export * from './monitor'
@@ -1,43 +0,0 @@
1
- // @ts-nocheck
2
- // Auto-generated by DjangoCFG - see CLAUDE.md
3
- 'use client';
4
-
5
- /**
6
- * SWR Hooks for Monitor
7
- *
8
- * React hooks powered by SWR for data fetching with automatic caching,
9
- * revalidation, and optimistic updates.
10
- *
11
- * Usage:
12
- * ```typescript
13
- * // Query hooks (GET)
14
- * const { data, error, isLoading } = useUsers({ page: 1 })
15
- *
16
- * // Mutation hooks (POST/PUT/PATCH/DELETE)
17
- * const createUser = useCreateUser()
18
- * await createUser({ name: 'John', email: 'john@example.com' })
19
- * ```
20
- */
21
- import { useSWRConfig } from 'swr'
22
- import * as Fetchers from '../fetchers/monitor'
23
- import type { API } from '../../index'
24
- import type { IngestBatchRequest } from '../schemas/IngestBatchRequest.schema'
25
-
26
- /**
27
- * Ingest browser events
28
- *
29
- * @method POST
30
- * @path /cfg/monitor/ingest/
31
- */
32
- export function useCreateMonitorIngestCreate() {
33
- const { mutate } = useSWRConfig()
34
-
35
- return async (data: IngestBatchRequest, client?: API): Promise<any> => {
36
- const result = await Fetchers.createMonitorIngestCreate(data, client)
37
- // Revalidate related queries
38
- mutate('cfg-monitor-ingest')
39
- return result
40
- }
41
- }
42
-
43
-
@@ -1,34 +0,0 @@
1
- /**
2
- * Zod schema for FrontendEventIngestRequest
3
- *
4
- * This schema provides runtime validation and type inference.
5
- * * Single browser event payload.
6
- * */
7
- import { z } from 'zod'
8
- import * as Enums from '../../enums'
9
-
10
- /**
11
- * Single browser event payload.
12
- */
13
- export const FrontendEventIngestRequestSchema = z.object({
14
- event_type: z.nativeEnum(Enums.FrontendEventIngestRequestEventType),
15
- message: z.string().min(1).max(5000),
16
- level: z.nativeEnum(Enums.FrontendEventIngestRequestLevel).optional(),
17
- stack_trace: z.string().max(10000).optional(),
18
- url: z.string().max(2000).optional(),
19
- fingerprint: z.string().max(64).optional(),
20
- http_status: z.number().int().nullable().optional(),
21
- http_method: z.string().max(10).optional(),
22
- http_url: z.string().max(2000).optional(),
23
- session_id: z.string().max(64).optional(),
24
- user_agent: z.string().max(500).optional(),
25
- build_id: z.string().max(100).optional(),
26
- environment: z.string().max(20).optional(),
27
- extra: z.record(z.string(), z.any()).optional(),
28
- project_name: z.string().max(100).optional(),
29
- })
30
-
31
- /**
32
- * Infer TypeScript type from Zod schema
33
- */
34
- export type FrontendEventIngestRequest = z.infer<typeof FrontendEventIngestRequestSchema>
@@ -1,20 +0,0 @@
1
- /**
2
- * Zod schema for IngestBatchRequest
3
- *
4
- * This schema provides runtime validation and type inference.
5
- * * Batch of up to 50 browser events.
6
- * */
7
- import { z } from 'zod'
8
- import { FrontendEventIngestRequestSchema } from './FrontendEventIngestRequest.schema'
9
-
10
- /**
11
- * Batch of up to 50 browser events.
12
- */
13
- export const IngestBatchRequestSchema = z.object({
14
- events: z.array(FrontendEventIngestRequestSchema),
15
- })
16
-
17
- /**
18
- * Infer TypeScript type from Zod schema
19
- */
20
- export type IngestBatchRequest = z.infer<typeof IngestBatchRequestSchema>
@@ -1,22 +0,0 @@
1
- // @ts-nocheck
2
- // Auto-generated by DjangoCFG - see CLAUDE.md
3
- /**
4
- * Zod Schemas - Runtime validation and type inference
5
- *
6
- * Auto-generated from OpenAPI specification.
7
- * Provides runtime validation for API requests and responses.
8
- *
9
- * Usage:
10
- * ```typescript
11
- * import { UserSchema } from './schemas'
12
- *
13
- * // Validate data
14
- * const user = UserSchema.parse(data)
15
- *
16
- * // Type inference
17
- * type User = z.infer<typeof UserSchema>
18
- * ```
19
- */
20
-
21
- export * from './FrontendEventIngestRequest.schema'
22
- export * from './IngestBatchRequest.schema'
@@ -1,181 +0,0 @@
1
- // @ts-nocheck
2
- // Auto-generated by DjangoCFG - see CLAUDE.md
3
- /**
4
- * Global API Instance - Singleton configuration with auto-configuration support
5
- *
6
- * This module provides a global API instance that auto-configures from
7
- * environment variables or can be configured manually.
8
- *
9
- * AUTO-CONFIGURATION (recommended):
10
- * Set one of these environment variables and the API will auto-configure:
11
- * - NEXT_PUBLIC_API_URL (Next.js)
12
- * - VITE_API_URL (Vite)
13
- * - REACT_APP_API_URL (Create React App)
14
- * - API_URL (generic)
15
- *
16
- * Then just use fetchers and hooks directly:
17
- * ```typescript
18
- * import { getUsers } from './_utils/fetchers'
19
- * const users = await getUsers({ page: 1 })
20
- * ```
21
- *
22
- * MANUAL CONFIGURATION:
23
- * ```typescript
24
- * import { configureAPI } from './api-instance'
25
- *
26
- * configureAPI({
27
- * baseUrl: 'https://api.example.com',
28
- * token: 'your-jwt-token'
29
- * })
30
- * ```
31
- *
32
- * For SSR or multiple instances:
33
- * ```typescript
34
- * import { API } from './index'
35
- * import { getUsers } from './_utils/fetchers'
36
- *
37
- * const api = new API('https://api.example.com')
38
- * const users = await getUsers({ page: 1 }, api)
39
- * ```
40
- */
41
-
42
- import { API, type APIOptions } from './index'
43
-
44
- let globalAPI: API | null = null
45
- let autoConfigAttempted = false
46
-
47
- /**
48
- * Auto-configure from environment variable if available (Next.js pattern)
49
- * This allows hooks and fetchers to work without explicit configureAPI() call
50
- *
51
- * Supported environment variables:
52
- * - NEXT_PUBLIC_API_URL (Next.js)
53
- * - VITE_API_URL (Vite)
54
- * - REACT_APP_API_URL (Create React App)
55
- * - API_URL (generic)
56
- */
57
- function tryAutoConfigureFromEnv(): void {
58
- // Only attempt once
59
- if (autoConfigAttempted) return
60
- autoConfigAttempted = true
61
-
62
- // Skip if already configured
63
- if (globalAPI) return
64
-
65
- // Skip if process is not available (pure browser without bundler)
66
- if (typeof process === 'undefined' || !process.env) return
67
-
68
- // Try different environment variable patterns
69
- const baseUrl =
70
- process.env.NEXT_PUBLIC_API_URL ||
71
- process.env.VITE_API_URL ||
72
- process.env.REACT_APP_API_URL ||
73
- process.env.API_URL
74
-
75
- if (baseUrl) {
76
- globalAPI = new API(baseUrl)
77
- }
78
- }
79
-
80
- /**
81
- * Get the global API instance
82
- * Auto-configures from environment variables on first call if not manually configured.
83
- * @throws Error if API is not configured and no env variable is set
84
- */
85
- export function getAPIInstance(): API {
86
- // Try auto-configuration on first access (lazy initialization)
87
- tryAutoConfigureFromEnv()
88
-
89
- if (!globalAPI) {
90
- throw new Error(
91
- 'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\n' +
92
- 'Example:\n' +
93
- ' import { configureAPI } from "./api-instance"\n' +
94
- ' configureAPI({ baseUrl: "https://api.example.com" })\n\n' +
95
- 'Or set environment variable: NEXT_PUBLIC_API_URL, VITE_API_URL, or REACT_APP_API_URL'
96
- )
97
- }
98
- return globalAPI
99
- }
100
-
101
- /**
102
- * Check if API is configured (or can be auto-configured)
103
- */
104
- export function isAPIConfigured(): boolean {
105
- tryAutoConfigureFromEnv()
106
- return globalAPI !== null
107
- }
108
-
109
- /**
110
- * Configure the global API instance
111
- *
112
- * @param baseUrl - Base URL for the API
113
- * @param options - Optional configuration (storage, retry, logger)
114
- *
115
- * @example
116
- * ```typescript
117
- * configureAPI({
118
- * baseUrl: 'https://api.example.com',
119
- * token: 'jwt-token',
120
- * options: {
121
- * retryConfig: { maxRetries: 3 },
122
- * loggerConfig: { enabled: true }
123
- * }
124
- * })
125
- * ```
126
- */
127
- export function configureAPI(config: {
128
- baseUrl: string
129
- token?: string
130
- refreshToken?: string
131
- options?: APIOptions
132
- }): API {
133
- globalAPI = new API(config.baseUrl, config.options)
134
-
135
- if (config.token) {
136
- globalAPI.setToken(config.token, config.refreshToken)
137
- }
138
-
139
- return globalAPI
140
- }
141
-
142
- /**
143
- * Reconfigure the global API instance with new settings
144
- * Useful for updating tokens or base URL
145
- */
146
- export function reconfigureAPI(updates: {
147
- baseUrl?: string
148
- token?: string
149
- refreshToken?: string
150
- }): API {
151
- const instance = getAPIInstance()
152
-
153
- if (updates.baseUrl) {
154
- instance.setBaseUrl(updates.baseUrl)
155
- }
156
-
157
- if (updates.token) {
158
- instance.setToken(updates.token, updates.refreshToken)
159
- }
160
-
161
- return instance
162
- }
163
-
164
- /**
165
- * Clear tokens from the global API instance
166
- */
167
- export function clearAPITokens(): void {
168
- const instance = getAPIInstance()
169
- instance.clearTokens()
170
- }
171
-
172
- /**
173
- * Reset the global API instance
174
- * Useful for testing or logout scenarios
175
- */
176
- export function resetAPI(): void {
177
- if (globalAPI) {
178
- globalAPI.clearTokens()
179
- }
180
- globalAPI = null
181
- }