@djangocfg/api 2.1.331 → 2.1.333
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/auth-server.cjs +1130 -1067
- package/dist/auth-server.cjs.map +1 -1
- package/dist/auth-server.mjs +1130 -1067
- package/dist/auth-server.mjs.map +1 -1
- package/dist/auth.cjs +1229 -1166
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs +1229 -1166
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +210 -974
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.d.cts +24 -49
- package/dist/clients.d.ts +24 -49
- package/dist/clients.mjs +210 -974
- package/dist/clients.mjs.map +1 -1
- package/dist/index.cjs +1199 -1099
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +673 -657
- package/dist/index.d.ts +673 -657
- package/dist/index.mjs +1199 -1099
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/_cfg_accounts/api.ts +29 -82
- package/src/_api/generated/_cfg_accounts/index.ts +4 -4
- package/src/_api/generated/_cfg_centrifugo/api.ts +29 -82
- package/src/_api/generated/_cfg_centrifugo/index.ts +4 -4
- package/src/_api/generated/_cfg_totp/api.ts +29 -82
- package/src/_api/generated/_cfg_totp/index.ts +4 -4
- package/src/_api/generated/client.gen.ts +4 -0
- package/src/_api/generated/helpers/auth.ts +240 -0
- package/src/_api/generated/helpers/index.ts +1 -0
- package/src/_api/generated/index.ts +17 -13
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
// AUTO-GENERATED by django_generator / ts_extras.wrapper
|
|
2
|
+
// Global auth store. Wired into the shared `client` from `client.gen.ts`
|
|
3
|
+
// via `installAuthOnClient(client)` — called synchronously by the
|
|
4
|
+
// post-processed bottom of client.gen.ts. No circular import here.
|
|
5
|
+
// DO NOT EDIT — re-run `make gen`.
|
|
6
|
+
|
|
7
|
+
const ACCESS_KEY = 'cfg.access_token';
|
|
8
|
+
const REFRESH_KEY = 'cfg.refresh_token';
|
|
9
|
+
const API_KEY_KEY = 'cfg.api_key';
|
|
10
|
+
|
|
11
|
+
const isBrowser = typeof window !== 'undefined';
|
|
12
|
+
|
|
13
|
+
export type StorageMode = 'localStorage' | 'cookie';
|
|
14
|
+
|
|
15
|
+
// ── Storage backends (browser-only; server-side reads return null) ─────────
|
|
16
|
+
|
|
17
|
+
interface KVStore {
|
|
18
|
+
get(key: string): string | null;
|
|
19
|
+
set(key: string, value: string | null): void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const localStorageBackend: KVStore = {
|
|
23
|
+
get(key) {
|
|
24
|
+
if (!isBrowser) return null;
|
|
25
|
+
try { return window.localStorage.getItem(key); } catch { return null; }
|
|
26
|
+
},
|
|
27
|
+
set(key, value) {
|
|
28
|
+
if (!isBrowser) return;
|
|
29
|
+
try {
|
|
30
|
+
if (value === null) window.localStorage.removeItem(key);
|
|
31
|
+
else window.localStorage.setItem(key, value);
|
|
32
|
+
} catch {}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** 30 days, matches typical refresh-token lifetime. */
|
|
37
|
+
const COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
|
|
38
|
+
|
|
39
|
+
const cookieBackend: KVStore = {
|
|
40
|
+
get(key) {
|
|
41
|
+
if (!isBrowser) return null;
|
|
42
|
+
try {
|
|
43
|
+
const re = new RegExp(`(?:^|;\\s*)${encodeURIComponent(key)}=([^;]*)`);
|
|
44
|
+
const m = document.cookie.match(re);
|
|
45
|
+
return m ? decodeURIComponent(m[1]) : null;
|
|
46
|
+
} catch { return null; }
|
|
47
|
+
},
|
|
48
|
+
set(key, value) {
|
|
49
|
+
if (!isBrowser) return;
|
|
50
|
+
try {
|
|
51
|
+
const k = encodeURIComponent(key);
|
|
52
|
+
const secure = window.location.protocol === 'https:' ? '; Secure' : '';
|
|
53
|
+
if (value === null) {
|
|
54
|
+
document.cookie = `${k}=; Path=/; Max-Age=0; SameSite=Lax${secure}`;
|
|
55
|
+
} else {
|
|
56
|
+
const v = encodeURIComponent(value);
|
|
57
|
+
document.cookie = `${k}=${v}; Path=/; Max-Age=${COOKIE_MAX_AGE}; SameSite=Lax${secure}`;
|
|
58
|
+
}
|
|
59
|
+
} catch {}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
let _storage: KVStore = localStorageBackend;
|
|
64
|
+
let _storageMode: StorageMode = 'localStorage';
|
|
65
|
+
|
|
66
|
+
/** Detect locale from `NEXT_LOCALE` cookie or `navigator.language`. */
|
|
67
|
+
function detectLocale(): string | null {
|
|
68
|
+
try {
|
|
69
|
+
if (typeof document !== 'undefined') {
|
|
70
|
+
const m = document.cookie.match(/(?:^|;\s*)NEXT_LOCALE=([^;]*)/);
|
|
71
|
+
if (m) return decodeURIComponent(m[1]);
|
|
72
|
+
}
|
|
73
|
+
if (typeof navigator !== 'undefined' && navigator.language) {
|
|
74
|
+
return navigator.language;
|
|
75
|
+
}
|
|
76
|
+
} catch {}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Default baseUrl from `NEXT_PUBLIC_API_URL` (empty for static builds). */
|
|
81
|
+
function defaultBaseUrl(): string {
|
|
82
|
+
try {
|
|
83
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
84
|
+
if (process.env.NEXT_PUBLIC_STATIC_BUILD === 'true') return '';
|
|
85
|
+
return process.env.NEXT_PUBLIC_API_URL || '';
|
|
86
|
+
}
|
|
87
|
+
} catch {}
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Default API key fallback from `NEXT_PUBLIC_API_KEY`. */
|
|
92
|
+
function defaultApiKey(): string | null {
|
|
93
|
+
try {
|
|
94
|
+
if (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_API_KEY) {
|
|
95
|
+
return process.env.NEXT_PUBLIC_API_KEY;
|
|
96
|
+
}
|
|
97
|
+
} catch {}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ── In-memory overrides (win over storage / env) ───────────────────────────
|
|
102
|
+
let _localeOverride: string | null = null;
|
|
103
|
+
let _apiKeyOverride: string | null = null;
|
|
104
|
+
let _baseUrlOverride: string | null = null;
|
|
105
|
+
let _withCredentials = true;
|
|
106
|
+
let _onUnauthorized: ((response: Response) => void) | null = null;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Captured reference to the shared Hey API client. Set exactly once by
|
|
110
|
+
* `installAuthOnClient(client)` (called from client.gen.ts). All `auth.set*`
|
|
111
|
+
* methods that mutate transport config (baseUrl / credentials) push through
|
|
112
|
+
* this reference. Until installed, those mutations are silently buffered as
|
|
113
|
+
* in-memory state — the next request after install will pick them up.
|
|
114
|
+
*/
|
|
115
|
+
type HeyClient = {
|
|
116
|
+
setConfig(opts: Record<string, unknown>): void;
|
|
117
|
+
interceptors: {
|
|
118
|
+
request: { use(fn: (req: Request) => Request | Promise<Request>): void };
|
|
119
|
+
response: { use(fn: (res: Response, req: Request) => Response | Promise<Response>): void };
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
let _client: HeyClient | null = null;
|
|
123
|
+
|
|
124
|
+
function pushClientConfig(): void {
|
|
125
|
+
if (!_client) return;
|
|
126
|
+
_client.setConfig({
|
|
127
|
+
baseUrl: auth.getBaseUrl(),
|
|
128
|
+
credentials: _withCredentials ? 'include' : 'same-origin',
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Global auth/config store. All getters read live state every call —
|
|
134
|
+
* the interceptor below uses these to attach headers per-request.
|
|
135
|
+
*
|
|
136
|
+
* Default storage backend is `localStorage`. Switch to cookies (e.g.
|
|
137
|
+
* for Next.js SSR cookie access) via `auth.setStorageMode('cookie')`
|
|
138
|
+
* early in the app bootstrap.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* import { auth } from '@your/api';
|
|
142
|
+
* auth.setToken(jwt);
|
|
143
|
+
* auth.clearTokens();
|
|
144
|
+
* auth.setStorageMode('cookie');
|
|
145
|
+
*/
|
|
146
|
+
export const auth = {
|
|
147
|
+
// ── Storage mode ──────────────────────────────────────────────────
|
|
148
|
+
getStorageMode(): StorageMode { return _storageMode; },
|
|
149
|
+
setStorageMode(mode: StorageMode): void {
|
|
150
|
+
_storageMode = mode;
|
|
151
|
+
_storage = mode === 'cookie' ? cookieBackend : localStorageBackend;
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
// ── Bearer token ──────────────────────────────────────────────────
|
|
155
|
+
getToken(): string | null { return _storage.get(ACCESS_KEY); },
|
|
156
|
+
setToken(token: string | null): void { _storage.set(ACCESS_KEY, token); },
|
|
157
|
+
getRefreshToken(): string | null { return _storage.get(REFRESH_KEY); },
|
|
158
|
+
setRefreshToken(token: string | null): void { _storage.set(REFRESH_KEY, token); },
|
|
159
|
+
clearTokens(): void { _storage.set(ACCESS_KEY, null); _storage.set(REFRESH_KEY, null); },
|
|
160
|
+
isAuthenticated(): boolean { return _storage.get(ACCESS_KEY) !== null; },
|
|
161
|
+
|
|
162
|
+
// ── API key ───────────────────────────────────────────────────────
|
|
163
|
+
getApiKey(): string | null {
|
|
164
|
+
return _apiKeyOverride ?? _storage.get(API_KEY_KEY) ?? defaultApiKey();
|
|
165
|
+
},
|
|
166
|
+
setApiKey(key: string | null): void { _apiKeyOverride = key; },
|
|
167
|
+
setApiKeyPersist(key: string | null): void {
|
|
168
|
+
_apiKeyOverride = key;
|
|
169
|
+
_storage.set(API_KEY_KEY, key);
|
|
170
|
+
},
|
|
171
|
+
clearApiKey(): void { _apiKeyOverride = null; _storage.set(API_KEY_KEY, null); },
|
|
172
|
+
|
|
173
|
+
// ── Locale ────────────────────────────────────────────────────────
|
|
174
|
+
getLocale(): string | null { return _localeOverride ?? detectLocale(); },
|
|
175
|
+
setLocale(locale: string | null): void { _localeOverride = locale; },
|
|
176
|
+
|
|
177
|
+
// ── Base URL ──────────────────────────────────────────────────────
|
|
178
|
+
getBaseUrl(): string {
|
|
179
|
+
const url = (_baseUrlOverride ?? defaultBaseUrl());
|
|
180
|
+
return url.replace(/\/$/, '');
|
|
181
|
+
},
|
|
182
|
+
setBaseUrl(url: string | null): void {
|
|
183
|
+
_baseUrlOverride = url ? url.replace(/\/$/, '') : null;
|
|
184
|
+
pushClientConfig();
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// ── Credentials toggle ────────────────────────────────────────────
|
|
188
|
+
getWithCredentials(): boolean { return _withCredentials; },
|
|
189
|
+
setWithCredentials(value: boolean): void {
|
|
190
|
+
_withCredentials = value;
|
|
191
|
+
pushClientConfig();
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
// ── 401 handler ───────────────────────────────────────────────────
|
|
195
|
+
onUnauthorized(cb: ((response: Response) => void) | null): void {
|
|
196
|
+
_onUnauthorized = cb;
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Wire the shared client to the global auth store. Called exactly
|
|
202
|
+
* once from `client.gen.ts` (post-processed) right after
|
|
203
|
+
* `createClient()`. Synchronous — no microtask, no TDZ races.
|
|
204
|
+
*
|
|
205
|
+
* Safe to call from server / SSR: storage backends short-circuit on
|
|
206
|
+
* non-browser environments, so headers populated by the interceptor
|
|
207
|
+
* are simply absent server-side (which is the correct behaviour
|
|
208
|
+
* unless the caller explicitly sets a server-side token).
|
|
209
|
+
*/
|
|
210
|
+
export function installAuthOnClient(client: HeyClient): void {
|
|
211
|
+
if (_client) return; // idempotent
|
|
212
|
+
_client = client;
|
|
213
|
+
|
|
214
|
+
client.setConfig({
|
|
215
|
+
baseUrl: auth.getBaseUrl(),
|
|
216
|
+
credentials: _withCredentials ? 'include' : 'same-origin',
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
client.interceptors.request.use((request) => {
|
|
220
|
+
const token = auth.getToken();
|
|
221
|
+
if (token) request.headers.set('Authorization', `Bearer ${token}`);
|
|
222
|
+
|
|
223
|
+
const locale = auth.getLocale();
|
|
224
|
+
if (locale) request.headers.set('Accept-Language', locale);
|
|
225
|
+
|
|
226
|
+
const apiKey = auth.getApiKey();
|
|
227
|
+
if (apiKey) request.headers.set('X-API-Key', apiKey);
|
|
228
|
+
|
|
229
|
+
return request;
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
client.interceptors.response.use((response) => {
|
|
233
|
+
if (response.status === 401 && _onUnauthorized) {
|
|
234
|
+
try { _onUnauthorized(response); } catch {}
|
|
235
|
+
}
|
|
236
|
+
return response;
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export type Auth = typeof auth;
|
|
@@ -1,27 +1,31 @@
|
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
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';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// Global auth/config store — single source of truth.
|
|
10
|
+
export { auth, type Auth } from './helpers/auth';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
import { API as CfgAccountsAPI } from './_cfg_accounts';
|
|
13
|
+
import { API as CfgCentrifugoAPI } from './_cfg_centrifugo';
|
|
14
|
+
import { API as CfgTotpAPI } from './_cfg_totp';
|
|
15
15
|
|
|
16
|
-
//
|
|
17
|
-
//
|
|
16
|
+
// Singletons for ergonomic access (`import { apiAccounts } from '@your/api'`).
|
|
17
|
+
// All instances share the same global `auth` store.
|
|
18
|
+
export const CfgAccountsApi = new CfgAccountsAPI();
|
|
19
|
+
export const CfgCentrifugoApi = new CfgCentrifugoAPI();
|
|
20
|
+
export const CfgTotpApi = new CfgTotpAPI();
|
|
21
|
+
|
|
22
|
+
// Per-group wrapper classes (e.g. for tests / SSR isolation of options).
|
|
18
23
|
export { API as CfgAccountsAPI } from './_cfg_accounts';
|
|
19
24
|
export { API as CfgCentrifugoAPI } from './_cfg_centrifugo';
|
|
20
25
|
export { API as CfgTotpAPI } from './_cfg_totp';
|
|
21
26
|
|
|
22
27
|
// Hey API SDK classes — one per OpenAPI tag. Lets consumers call
|
|
23
|
-
// `Centrifugo.cfgCentrifugoAuthTokenRetrieve({...})` directly
|
|
24
|
-
// going through the wrapper singleton.
|
|
28
|
+
// `Centrifugo.cfgCentrifugoAuthTokenRetrieve({...})` directly.
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
// Shared utilities (errors, storage adapters, logger).
|