@djangocfg/monitor 2.1.327 → 2.1.332
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/dist/client.cjs +239 -147
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +9 -9
- package/dist/client.d.ts +9 -9
- package/dist/client.mjs +239 -147
- package/dist/client.mjs.map +1 -1
- package/dist/index.cjs +217 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.mjs +217 -146
- package/dist/index.mjs.map +1 -1
- package/dist/server.cjs +237 -145
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +9 -9
- package/dist/server.d.ts +9 -9
- package/dist/server.mjs +237 -145
- package/dist/server.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/BaseClient.ts +2 -2
- package/src/_api/generated/_cfg_monitor/api.ts +67 -0
- package/src/_api/generated/{cfg_monitor → _cfg_monitor}/events.ts +3 -3
- package/src/_api/generated/{cfg_monitor → _cfg_monitor}/hooks/index.ts +1 -1
- package/src/_api/generated/{cfg_monitor → _cfg_monitor}/hooks/useCfgMonitorIngestCreate.ts +3 -3
- package/src/_api/generated/{cfg_monitor → _cfg_monitor}/index.ts +6 -6
- package/src/_api/generated/{cfg_monitor → _cfg_monitor}/schemas/EventTypeEnum.ts +2 -2
- package/src/_api/generated/_cfg_monitor/schemas/FrontendEventIngestRequest.ts +27 -0
- package/src/_api/generated/{cfg_monitor → _cfg_monitor}/schemas/IngestBatchRequest.ts +2 -2
- package/src/_api/generated/{cfg_monitor → _cfg_monitor}/schemas/LevelEnum.ts +2 -2
- package/src/_api/generated/_cfg_monitor/sdk.gen.ts +5 -0
- package/src/_api/generated/_cfg_monitor/types.gen.ts +5 -0
- package/src/_api/generated/{cfg_monitor/client.gen.ts → client.gen.ts} +3 -0
- package/src/_api/generated/helpers/auth.ts +223 -0
- package/src/_api/generated/{_shared → helpers}/index.ts +1 -0
- package/src/_api/generated/index.ts +16 -12
- package/src/_api/index.ts +2 -2
- package/src/client/transport/ingest.ts +1 -1
- package/src/server/index.ts +1 -1
- package/src/_api/generated/cfg_monitor/api.ts +0 -122
- package/src/_api/generated/cfg_monitor/schemas/FrontendEventIngestRequest.ts +0 -27
- package/src/_api/generated/{cfg_monitor → _cfg_monitor}/schemas/index.ts +0 -0
- package/src/_api/generated/{cfg_monitor/client → client}/client.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/client → client}/index.ts +0 -0
- package/src/_api/generated/{cfg_monitor/client → client}/types.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/client → client}/utils.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/core → core}/auth.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/core → core}/bodySerializer.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/core → core}/params.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/core → core}/pathSerializer.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/core → core}/queryKeySerializer.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/core → core}/serverSentEvents.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/core → core}/types.gen.ts +0 -0
- package/src/_api/generated/{cfg_monitor/core → core}/utils.gen.ts +0 -0
- package/src/_api/generated/{_shared → helpers}/errors.ts +0 -0
- package/src/_api/generated/{_shared → helpers}/logger.ts +0 -0
- package/src/_api/generated/{_shared → helpers}/storage.ts +0 -0
- package/src/_api/generated/{_shared → helpers}/validation-events.ts +0 -0
- package/src/_api/generated/{cfg_monitor/sdk.gen.ts → sdk.gen.ts} +0 -0
- package/src/_api/generated/{cfg_monitor/types.gen.ts → types.gen.ts} +9 -9
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// AUTO-GENERATED by cmdop_server / devtools.generator.ts_extras
|
|
2
|
+
// Source: OpenAPI 3.1 components.schemas
|
|
3
|
+
// DO NOT EDIT — re-run `make gen-clients`.
|
|
4
|
+
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { EventTypeEnumSchema } from "./EventTypeEnum";
|
|
7
|
+
import { LevelEnumSchema } from "./LevelEnum";
|
|
8
|
+
|
|
9
|
+
export const FrontendEventIngestRequestSchema = z.object({
|
|
10
|
+
build_id: z.string().max(100).default("").optional(),
|
|
11
|
+
environment: z.string().max(20).default("").optional(),
|
|
12
|
+
event_type: EventTypeEnumSchema,
|
|
13
|
+
extra: z.unknown().optional(),
|
|
14
|
+
fingerprint: z.string().max(64).default("").optional(),
|
|
15
|
+
http_method: z.string().max(10).default("").optional(),
|
|
16
|
+
http_status: z.number().int().nullable().optional(),
|
|
17
|
+
http_url: z.string().max(2000).default("").optional(),
|
|
18
|
+
level: LevelEnumSchema.optional(),
|
|
19
|
+
message: z.string().min(1).max(5000),
|
|
20
|
+
project_name: z.string().max(100).default("").optional(),
|
|
21
|
+
session_id: z.string().max(64).default("").optional(),
|
|
22
|
+
stack_trace: z.string().max(10000).default("").optional(),
|
|
23
|
+
url: z.string().max(2000).default("").optional(),
|
|
24
|
+
user_agent: z.string().max(500).default("").optional(),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export type FrontendEventIngestRequest = z.infer<typeof FrontendEventIngestRequestSchema>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// AUTO-GENERATED by
|
|
1
|
+
// AUTO-GENERATED by cmdop_server / devtools.generator.ts_extras
|
|
2
2
|
// Source: OpenAPI 3.1 components.schemas
|
|
3
|
-
// DO NOT EDIT — re-run `make gen`.
|
|
3
|
+
// DO NOT EDIT — re-run `make gen-clients`.
|
|
4
4
|
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { FrontendEventIngestRequestSchema } from "./FrontendEventIngestRequest";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// AUTO-GENERATED by
|
|
1
|
+
// AUTO-GENERATED by cmdop_server / devtools.generator.ts_extras
|
|
2
2
|
// Source: OpenAPI 3.1 components.schemas
|
|
3
|
-
// DO NOT EDIT — re-run `make gen`.
|
|
3
|
+
// DO NOT EDIT — re-run `make gen-clients`.
|
|
4
4
|
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
|
|
@@ -14,3 +14,6 @@ import type { ClientOptions as ClientOptions2 } from './types.gen';
|
|
|
14
14
|
export type CreateClientConfig<T extends ClientOptions = ClientOptions2> = (override?: Config<ClientOptions & T>) => Config<Required<ClientOptions> & T>;
|
|
15
15
|
|
|
16
16
|
export const client = createClient(createConfig<ClientOptions2>({ baseUrl: 'http://localhost:8000' }));
|
|
17
|
+
|
|
18
|
+
// auto-init: load auth interceptor
|
|
19
|
+
import './helpers/auth';
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// AUTO-GENERATED by django_generator / ts_extras.wrapper
|
|
2
|
+
// Global auth store. ONE source of truth for token / API key / locale /
|
|
3
|
+
// baseUrl. Installs the request interceptor as a side-effect on import.
|
|
4
|
+
// DO NOT EDIT — re-run `make gen`.
|
|
5
|
+
|
|
6
|
+
import { client } from '../client.gen';
|
|
7
|
+
|
|
8
|
+
const ACCESS_KEY = 'cfg.access_token';
|
|
9
|
+
const REFRESH_KEY = 'cfg.refresh_token';
|
|
10
|
+
const API_KEY_KEY = 'cfg.api_key';
|
|
11
|
+
|
|
12
|
+
const isBrowser = typeof window !== 'undefined';
|
|
13
|
+
|
|
14
|
+
export type StorageMode = 'localStorage' | 'cookie';
|
|
15
|
+
|
|
16
|
+
// ── Storage backends (browser-only; server-side reads return null) ─────────
|
|
17
|
+
|
|
18
|
+
interface KVStore {
|
|
19
|
+
get(key: string): string | null;
|
|
20
|
+
set(key: string, value: string | null): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const localStorageBackend: KVStore = {
|
|
24
|
+
get(key) {
|
|
25
|
+
if (!isBrowser) return null;
|
|
26
|
+
try { return window.localStorage.getItem(key); } catch { return null; }
|
|
27
|
+
},
|
|
28
|
+
set(key, value) {
|
|
29
|
+
if (!isBrowser) return;
|
|
30
|
+
try {
|
|
31
|
+
if (value === null) window.localStorage.removeItem(key);
|
|
32
|
+
else window.localStorage.setItem(key, value);
|
|
33
|
+
} catch {}
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** 30 days, matches typical refresh-token lifetime. */
|
|
38
|
+
const COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
|
|
39
|
+
|
|
40
|
+
const cookieBackend: KVStore = {
|
|
41
|
+
get(key) {
|
|
42
|
+
if (!isBrowser) return null;
|
|
43
|
+
try {
|
|
44
|
+
const re = new RegExp(`(?:^|;\\s*)${encodeURIComponent(key)}=([^;]*)`);
|
|
45
|
+
const m = document.cookie.match(re);
|
|
46
|
+
return m ? decodeURIComponent(m[1]) : null;
|
|
47
|
+
} catch { return null; }
|
|
48
|
+
},
|
|
49
|
+
set(key, value) {
|
|
50
|
+
if (!isBrowser) return;
|
|
51
|
+
try {
|
|
52
|
+
const k = encodeURIComponent(key);
|
|
53
|
+
const secure = window.location.protocol === 'https:' ? '; Secure' : '';
|
|
54
|
+
if (value === null) {
|
|
55
|
+
document.cookie = `${k}=; Path=/; Max-Age=0; SameSite=Lax${secure}`;
|
|
56
|
+
} else {
|
|
57
|
+
const v = encodeURIComponent(value);
|
|
58
|
+
document.cookie = `${k}=${v}; Path=/; Max-Age=${COOKIE_MAX_AGE}; SameSite=Lax${secure}`;
|
|
59
|
+
}
|
|
60
|
+
} catch {}
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
let _storage: KVStore = localStorageBackend;
|
|
65
|
+
let _storageMode: StorageMode = 'localStorage';
|
|
66
|
+
|
|
67
|
+
/** Detect locale from `NEXT_LOCALE` cookie or `navigator.language`. */
|
|
68
|
+
function detectLocale(): string | null {
|
|
69
|
+
try {
|
|
70
|
+
if (typeof document !== 'undefined') {
|
|
71
|
+
const m = document.cookie.match(/(?:^|;\s*)NEXT_LOCALE=([^;]*)/);
|
|
72
|
+
if (m) return decodeURIComponent(m[1]);
|
|
73
|
+
}
|
|
74
|
+
if (typeof navigator !== 'undefined' && navigator.language) {
|
|
75
|
+
return navigator.language;
|
|
76
|
+
}
|
|
77
|
+
} catch {}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Default baseUrl from `NEXT_PUBLIC_API_URL` (empty for static builds). */
|
|
82
|
+
function defaultBaseUrl(): string {
|
|
83
|
+
try {
|
|
84
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
85
|
+
if (process.env.NEXT_PUBLIC_STATIC_BUILD === 'true') return '';
|
|
86
|
+
return process.env.NEXT_PUBLIC_API_URL || '';
|
|
87
|
+
}
|
|
88
|
+
} catch {}
|
|
89
|
+
return '';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Default API key fallback from `NEXT_PUBLIC_API_KEY`. */
|
|
93
|
+
function defaultApiKey(): string | null {
|
|
94
|
+
try {
|
|
95
|
+
if (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_API_KEY) {
|
|
96
|
+
return process.env.NEXT_PUBLIC_API_KEY;
|
|
97
|
+
}
|
|
98
|
+
} catch {}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ── In-memory overrides (win over storage / env) ───────────────────────────
|
|
103
|
+
let _localeOverride: string | null = null;
|
|
104
|
+
let _apiKeyOverride: string | null = null;
|
|
105
|
+
let _baseUrlOverride: string | null = null;
|
|
106
|
+
let _withCredentials = true;
|
|
107
|
+
let _onUnauthorized: ((response: Response) => void) | null = null;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Global auth/config store. All getters read live state every call —
|
|
111
|
+
* the interceptor below uses these to attach headers per-request.
|
|
112
|
+
*
|
|
113
|
+
* Default storage backend is `localStorage`. Switch to cookies (e.g.
|
|
114
|
+
* for Next.js SSR cookie access) via `auth.setStorageMode('cookie')`
|
|
115
|
+
* early in the app bootstrap.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* import { auth } from '@your/api';
|
|
119
|
+
*
|
|
120
|
+
* // After login
|
|
121
|
+
* auth.setToken(jwt);
|
|
122
|
+
* auth.setRefreshToken(refresh);
|
|
123
|
+
*
|
|
124
|
+
* // After logout
|
|
125
|
+
* auth.clearTokens();
|
|
126
|
+
*
|
|
127
|
+
* // Switch to cookie storage (call once during app init)
|
|
128
|
+
* auth.setStorageMode('cookie');
|
|
129
|
+
*/
|
|
130
|
+
export const auth = {
|
|
131
|
+
// ── Storage mode ──────────────────────────────────────────────────
|
|
132
|
+
getStorageMode(): StorageMode { return _storageMode; },
|
|
133
|
+
/**
|
|
134
|
+
* Switch the storage backend. Existing values in the *previous*
|
|
135
|
+
* backend are NOT migrated — set fresh values after switching.
|
|
136
|
+
*/
|
|
137
|
+
setStorageMode(mode: StorageMode): void {
|
|
138
|
+
_storageMode = mode;
|
|
139
|
+
_storage = mode === 'cookie' ? cookieBackend : localStorageBackend;
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
// ── Bearer token ──────────────────────────────────────────────────
|
|
143
|
+
getToken(): string | null { return _storage.get(ACCESS_KEY); },
|
|
144
|
+
setToken(token: string | null): void { _storage.set(ACCESS_KEY, token); },
|
|
145
|
+
getRefreshToken(): string | null { return _storage.get(REFRESH_KEY); },
|
|
146
|
+
setRefreshToken(token: string | null): void { _storage.set(REFRESH_KEY, token); },
|
|
147
|
+
clearTokens(): void { _storage.set(ACCESS_KEY, null); _storage.set(REFRESH_KEY, null); },
|
|
148
|
+
isAuthenticated(): boolean { return _storage.get(ACCESS_KEY) !== null; },
|
|
149
|
+
|
|
150
|
+
// ── API key ───────────────────────────────────────────────────────
|
|
151
|
+
/** In-memory API key. Falls back to storage, then NEXT_PUBLIC_API_KEY. */
|
|
152
|
+
getApiKey(): string | null {
|
|
153
|
+
return _apiKeyOverride ?? _storage.get(API_KEY_KEY) ?? defaultApiKey();
|
|
154
|
+
},
|
|
155
|
+
/** In-memory only (cleared on reload). */
|
|
156
|
+
setApiKey(key: string | null): void { _apiKeyOverride = key; },
|
|
157
|
+
/** Persist to active storage backend (localStorage or cookie). */
|
|
158
|
+
setApiKeyPersist(key: string | null): void {
|
|
159
|
+
_apiKeyOverride = key;
|
|
160
|
+
_storage.set(API_KEY_KEY, key);
|
|
161
|
+
},
|
|
162
|
+
clearApiKey(): void { _apiKeyOverride = null; _storage.set(API_KEY_KEY, null); },
|
|
163
|
+
|
|
164
|
+
// ── Locale ────────────────────────────────────────────────────────
|
|
165
|
+
/** Override locale → falls back to NEXT_LOCALE cookie / navigator.language. */
|
|
166
|
+
getLocale(): string | null { return _localeOverride ?? detectLocale(); },
|
|
167
|
+
setLocale(locale: string | null): void { _localeOverride = locale; },
|
|
168
|
+
|
|
169
|
+
// ── Base URL ──────────────────────────────────────────────────────
|
|
170
|
+
getBaseUrl(): string {
|
|
171
|
+
const url = (_baseUrlOverride ?? defaultBaseUrl());
|
|
172
|
+
return url.replace(/\/$/, '');
|
|
173
|
+
},
|
|
174
|
+
setBaseUrl(url: string | null): void {
|
|
175
|
+
_baseUrlOverride = url ? url.replace(/\/$/, '') : null;
|
|
176
|
+
client.setConfig({ baseUrl: this.getBaseUrl() });
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
// ── Credentials toggle (Django session/CSRF cross-origin) ─────────
|
|
180
|
+
getWithCredentials(): boolean { return _withCredentials; },
|
|
181
|
+
setWithCredentials(value: boolean): void {
|
|
182
|
+
_withCredentials = value;
|
|
183
|
+
client.setConfig({ credentials: value ? 'include' : 'same-origin' });
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
// ── 401 handler ───────────────────────────────────────────────────
|
|
187
|
+
/**
|
|
188
|
+
* Register a callback fired on every 401 response. Use this to wire
|
|
189
|
+
* a token-refresh flow or a forced logout. Setting `null` removes
|
|
190
|
+
* the handler.
|
|
191
|
+
*/
|
|
192
|
+
onUnauthorized(cb: ((response: Response) => void) | null): void {
|
|
193
|
+
_onUnauthorized = cb;
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// ── One-time client wiring (side-effect on first import) ───────────────────
|
|
198
|
+
client.setConfig({
|
|
199
|
+
baseUrl: auth.getBaseUrl(),
|
|
200
|
+
credentials: _withCredentials ? 'include' : 'same-origin',
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
client.interceptors.request.use((request) => {
|
|
204
|
+
const token = auth.getToken();
|
|
205
|
+
if (token) request.headers.set('Authorization', `Bearer ${token}`);
|
|
206
|
+
|
|
207
|
+
const locale = auth.getLocale();
|
|
208
|
+
if (locale) request.headers.set('Accept-Language', locale);
|
|
209
|
+
|
|
210
|
+
const apiKey = auth.getApiKey();
|
|
211
|
+
if (apiKey) request.headers.set('X-API-Key', apiKey);
|
|
212
|
+
|
|
213
|
+
return request;
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
client.interceptors.response.use((response) => {
|
|
217
|
+
if (response.status === 401 && _onUnauthorized) {
|
|
218
|
+
try { _onUnauthorized(response); } catch {}
|
|
219
|
+
}
|
|
220
|
+
return response;
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
export type Auth = typeof auth;
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
// AUTO-GENERATED by django_generator / ts_extras.wrapper
|
|
2
|
-
// Top-level barrel —
|
|
2
|
+
// Top-level barrel — global `auth` + per-group facades.
|
|
3
3
|
// DO NOT EDIT — re-run `make gen`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// Side-effect: ensure auth interceptor is installed even if consumers
|
|
6
|
+
// only ever import this barrel (it'll also load via client.gen.ts).
|
|
7
|
+
import './helpers/auth';
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
// Global auth/config store — single source of truth.
|
|
10
|
+
export { auth, type Auth } from './helpers/auth';
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
import { API as CfgMonitorAPI } from './_cfg_monitor';
|
|
11
13
|
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
export
|
|
14
|
+
// Singletons for ergonomic access (`import { apiAccounts } from '@your/api'`).
|
|
15
|
+
// All instances share the same global `auth` store.
|
|
16
|
+
export const CfgMonitorApi = new CfgMonitorAPI();
|
|
17
|
+
|
|
18
|
+
// Per-group wrapper classes (e.g. for tests / SSR isolation of options).
|
|
19
|
+
export { API as CfgMonitorAPI } from './_cfg_monitor';
|
|
15
20
|
|
|
16
21
|
// Hey API SDK classes — one per OpenAPI tag. Lets consumers call
|
|
17
|
-
// `Centrifugo.cfgCentrifugoAuthTokenRetrieve({...})` directly
|
|
18
|
-
|
|
19
|
-
export { Monitor } from './cfg_monitor';
|
|
22
|
+
// `Centrifugo.cfgCentrifugoAuthTokenRetrieve({...})` directly.
|
|
23
|
+
|
|
20
24
|
|
|
21
25
|
// Shared utilities (errors, storage adapters, logger).
|
|
22
|
-
export * from './
|
|
26
|
+
export * from './helpers';
|
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/
|
|
3
|
-
export { EventTypeEnum as EventType, LevelEnum as EventLevel } from './generated/
|
|
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/'
|
package/src/server/index.ts
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { configureMonitorApi, EventType, EventLevel } from '../_api'
|
|
26
|
-
import { Monitor } from '../_api/generated/
|
|
26
|
+
import { Monitor } from '../_api/generated/sdk.gen'
|
|
27
27
|
import type { FrontendEventIngestRequest } from '../_api'
|
|
28
28
|
import type { ServerMonitorConfig } from '../types'
|
|
29
29
|
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
// AUTO-GENERATED by django_generator / ts_extras.wrapper
|
|
2
|
-
// Self-contained API wrapper for this group. DO NOT EDIT — re-run `make gen`.
|
|
3
|
-
|
|
4
|
-
import { client } from './client.gen';
|
|
5
|
-
import type { StorageAdapter } from '../_shared/storage';
|
|
6
|
-
import { LocalStorageAdapter } from '../_shared/storage';
|
|
7
|
-
import { APILogger, type LoggerConfig } from '../_shared/logger';
|
|
8
|
-
|
|
9
|
-
import { Cfg } from './sdk.gen';
|
|
10
|
-
import { Monitor } from './sdk.gen';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const ACCESS_KEY = 'cfg.access_token';
|
|
14
|
-
const REFRESH_KEY = 'cfg.refresh_token';
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
/** Auto-detect locale from cookie NEXT_LOCALE or navigator.language. */
|
|
19
|
-
function detectLocale(): string | null {
|
|
20
|
-
try {
|
|
21
|
-
if (typeof document !== 'undefined') {
|
|
22
|
-
const m = document.cookie.match(/(?:^|;\s*)NEXT_LOCALE=([^;]*)/);
|
|
23
|
-
if (m) return decodeURIComponent(m[1]);
|
|
24
|
-
}
|
|
25
|
-
if (typeof navigator !== 'undefined' && navigator.language) {
|
|
26
|
-
return navigator.language;
|
|
27
|
-
}
|
|
28
|
-
} catch {}
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface APIOptions {
|
|
33
|
-
/** Override storage backend (LocalStorage by default; Memory for SSR/tests). */
|
|
34
|
-
storage?: StorageAdapter;
|
|
35
|
-
/** Logger config (defaults to dev-only). */
|
|
36
|
-
logger?: Partial<LoggerConfig>;
|
|
37
|
-
/** Locale for `Accept-Language`. If omitted, auto-detected from cookie/navigator. */
|
|
38
|
-
locale?: string;
|
|
39
|
-
/** API key sent as `X-API-Key`. Falls back to NEXT_PUBLIC_API_KEY. */
|
|
40
|
-
apiKey?: string;
|
|
41
|
-
/** Send Django session/CSRF cookies cross-origin. Defaults to true. */
|
|
42
|
-
withCredentials?: boolean;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Self-contained API wrapper for this group.
|
|
47
|
-
*
|
|
48
|
-
* Each group has its own client + interceptor + token store. The interceptor
|
|
49
|
-
* automatically attaches:
|
|
50
|
-
* - `Authorization: Bearer <jwt>` from storage
|
|
51
|
-
* - `Accept-Language` from `opts.locale` or `NEXT_LOCALE` cookie
|
|
52
|
-
* - `X-API-Key` from `opts.apiKey` or `NEXT_PUBLIC_API_KEY`
|
|
53
|
-
* - `credentials: 'include'` for Django session/CSRF cookies (toggle via opts)
|
|
54
|
-
*/
|
|
55
|
-
export class API {
|
|
56
|
-
private baseUrl: string;
|
|
57
|
-
private storage: StorageAdapter;
|
|
58
|
-
private locale: string | null;
|
|
59
|
-
private apiKey: string | null;
|
|
60
|
-
readonly logger: APILogger;
|
|
61
|
-
|
|
62
|
-
readonly cfg = Cfg;
|
|
63
|
-
readonly monitor = Monitor;
|
|
64
|
-
|
|
65
|
-
constructor(baseUrl: string, opts: APIOptions = {}) {
|
|
66
|
-
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
67
|
-
this.storage = opts.storage ?? new LocalStorageAdapter();
|
|
68
|
-
this.logger = new APILogger(opts.logger);
|
|
69
|
-
this.locale = opts.locale ?? null;
|
|
70
|
-
this.apiKey = opts.apiKey ?? (typeof process !== 'undefined' ? (process.env?.NEXT_PUBLIC_API_KEY ?? null) : null);
|
|
71
|
-
|
|
72
|
-
const credentials: RequestCredentials = (opts.withCredentials ?? true) ? 'include' : 'same-origin';
|
|
73
|
-
client.setConfig({ baseUrl: this.baseUrl, credentials });
|
|
74
|
-
|
|
75
|
-
client.interceptors.request.use((request) => {
|
|
76
|
-
const access = this.getToken();
|
|
77
|
-
if (access) request.headers.set('Authorization', `Bearer ${access}`);
|
|
78
|
-
|
|
79
|
-
const locale = this.locale ?? detectLocale();
|
|
80
|
-
if (locale) request.headers.set('Accept-Language', locale);
|
|
81
|
-
|
|
82
|
-
if (this.apiKey) request.headers.set('X-API-Key', this.apiKey);
|
|
83
|
-
|
|
84
|
-
return request;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// ── Base URL ────────────────────────────────────────────────────────────
|
|
91
|
-
getBaseUrl(): string { return this.baseUrl; }
|
|
92
|
-
setBaseUrl(url: string): void {
|
|
93
|
-
this.baseUrl = url.replace(/\/$/, '');
|
|
94
|
-
client.setConfig({ baseUrl: this.baseUrl });
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// ── Tokens ──────────────────────────────────────────────────────────────
|
|
98
|
-
getToken(): string | null { return this.storage.getItem(ACCESS_KEY); }
|
|
99
|
-
setToken(token: string | null): void {
|
|
100
|
-
if (token) this.storage.setItem(ACCESS_KEY, token);
|
|
101
|
-
else this.storage.removeItem(ACCESS_KEY);
|
|
102
|
-
}
|
|
103
|
-
getRefreshToken(): string | null { return this.storage.getItem(REFRESH_KEY); }
|
|
104
|
-
setRefreshToken(token: string | null): void {
|
|
105
|
-
if (token) this.storage.setItem(REFRESH_KEY, token);
|
|
106
|
-
else this.storage.removeItem(REFRESH_KEY);
|
|
107
|
-
}
|
|
108
|
-
clearToken(): void {
|
|
109
|
-
this.storage.removeItem(ACCESS_KEY);
|
|
110
|
-
this.storage.removeItem(REFRESH_KEY);
|
|
111
|
-
}
|
|
112
|
-
isAuthenticated(): boolean { return this.getToken() !== null; }
|
|
113
|
-
|
|
114
|
-
// ── Locale / API key ────────────────────────────────────────────────────
|
|
115
|
-
getLocale(): string | null { return this.locale ?? detectLocale(); }
|
|
116
|
-
setLocale(locale: string | null): void { this.locale = locale; }
|
|
117
|
-
getApiKey(): string | null { return this.apiKey; }
|
|
118
|
-
setApiKey(key: string | null): void { this.apiKey = key; }
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export { Cfg, Monitor };
|
|
122
|
-
export { client };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// AUTO-GENERATED by django-cfg / django_generator.ts_extras
|
|
2
|
-
// Source: OpenAPI 3.1 components.schemas
|
|
3
|
-
// DO NOT EDIT — re-run `make gen`.
|
|
4
|
-
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { EventTypeEnumSchema } from "./EventTypeEnum";
|
|
7
|
-
import { LevelEnumSchema } from "./LevelEnum";
|
|
8
|
-
|
|
9
|
-
export const FrontendEventIngestRequestSchema = z.object({
|
|
10
|
-
event_type: EventTypeEnumSchema,
|
|
11
|
-
message: z.string().min(1).max(5000),
|
|
12
|
-
level: LevelEnumSchema.optional(),
|
|
13
|
-
stack_trace: z.string().max(10000).optional(),
|
|
14
|
-
url: z.string().max(2000).optional(),
|
|
15
|
-
fingerprint: z.string().max(64).optional(),
|
|
16
|
-
http_status: z.number().int().nullable().optional(),
|
|
17
|
-
http_method: z.string().max(10).optional(),
|
|
18
|
-
http_url: z.string().max(2000).optional(),
|
|
19
|
-
session_id: z.string().max(64).optional(),
|
|
20
|
-
user_agent: z.string().max(500).optional(),
|
|
21
|
-
build_id: z.string().max(100).optional(),
|
|
22
|
-
environment: z.string().max(20).optional(),
|
|
23
|
-
extra: z.unknown().optional(),
|
|
24
|
-
project_name: z.string().max(100).optional(),
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
export type FrontendEventIngestRequest = z.infer<typeof FrontendEventIngestRequestSchema>;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -27,21 +27,21 @@ export enum EventTypeEnum {
|
|
|
27
27
|
* Single browser event payload.
|
|
28
28
|
*/
|
|
29
29
|
export type FrontendEventIngestRequest = {
|
|
30
|
+
build_id?: string;
|
|
31
|
+
environment?: string;
|
|
30
32
|
event_type: EventTypeEnum;
|
|
31
|
-
|
|
32
|
-
level?: LevelEnum;
|
|
33
|
-
stack_trace?: string;
|
|
34
|
-
url?: string;
|
|
33
|
+
extra?: unknown;
|
|
35
34
|
fingerprint?: string;
|
|
36
|
-
http_status?: number | null;
|
|
37
35
|
http_method?: string;
|
|
36
|
+
http_status?: number | null;
|
|
38
37
|
http_url?: string;
|
|
38
|
+
level?: LevelEnum;
|
|
39
|
+
message: string;
|
|
40
|
+
project_name?: string;
|
|
39
41
|
session_id?: string;
|
|
42
|
+
stack_trace?: string;
|
|
43
|
+
url?: string;
|
|
40
44
|
user_agent?: string;
|
|
41
|
-
build_id?: string;
|
|
42
|
-
environment?: string;
|
|
43
|
-
extra?: unknown;
|
|
44
|
-
project_name?: string;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
/**
|