@djangocfg/api 2.1.309 → 2.1.310
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 +18 -7
- package/dist/auth-server.cjs.map +1 -1
- package/dist/auth-server.mjs +18 -7
- package/dist/auth-server.mjs.map +1 -1
- package/dist/auth.cjs +54 -21
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs +54 -21
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +54 -21
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.d.cts +144 -144
- package/dist/clients.d.ts +144 -144
- package/dist/clients.mjs +54 -21
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +18 -7
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +92 -92
- package/dist/hooks.d.ts +92 -92
- package/dist/hooks.mjs +18 -7
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +36 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +111 -105
- package/dist/index.d.ts +111 -105
- package/dist/index.mjs +36 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/cfg_accounts/accounts/models.ts +25 -25
- package/src/_api/generated/cfg_accounts/accounts__oauth/models.ts +62 -62
- package/src/_api/generated/cfg_accounts/accounts__user_profile/models.ts +24 -24
- package/src/_api/generated/cfg_accounts/client.ts +3 -0
- package/src/_api/generated/cfg_accounts/http.ts +30 -7
- package/src/_api/generated/cfg_centrifugo/client.ts +3 -0
- package/src/_api/generated/cfg_centrifugo/http.ts +30 -7
- package/src/_api/generated/cfg_totp/client.ts +3 -0
- package/src/_api/generated/cfg_totp/http.ts +30 -7
- package/src/_api/generated/cfg_totp/totp__backup_codes/models.ts +10 -10
- package/src/_api/generated/cfg_totp/totp__totp_management/models.ts +10 -10
- package/src/_api/generated/cfg_totp/totp__totp_setup/models.ts +18 -18
- package/src/_api/generated/cfg_totp/totp__totp_verification/models.ts +18 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/api",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.310",
|
|
4
4
|
"description": "Auto-generated TypeScript API client with React hooks, SWR integration, and Zod validation for Django REST Framework backends",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"django",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@types/node": "^24.7.2",
|
|
86
86
|
"@types/react": "^19.1.0",
|
|
87
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
87
|
+
"@djangocfg/typescript-config": "^2.1.310",
|
|
88
88
|
"next": "^16.2.2",
|
|
89
89
|
"react": "^19.1.0",
|
|
90
90
|
"tsup": "^8.5.0",
|
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Auto-generated by DjangoCFG - see CLAUDE.md
|
|
3
|
-
/**
|
|
4
|
-
* Serializer for OTP verification.
|
|
5
|
-
*
|
|
6
|
-
* Request model (no read-only fields).
|
|
7
|
-
*/
|
|
8
|
-
export interface OTPVerifyRequest {
|
|
9
|
-
/** Email address used for OTP request */
|
|
10
|
-
identifier: string;
|
|
11
|
-
otp: string;
|
|
12
|
-
/** Source URL for tracking login (e.g., https://my.djangocfg.com) */
|
|
13
|
-
source_url?: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
3
|
/**
|
|
17
4
|
* OTP verification response. When 2FA is required: - requires_2fa: True -
|
|
18
5
|
* session_id: UUID of 2FA verification session - refresh/access/user: null
|
|
@@ -35,18 +22,6 @@ export interface OTPVerifyResponse {
|
|
|
35
22
|
should_prompt_2fa?: boolean;
|
|
36
23
|
}
|
|
37
24
|
|
|
38
|
-
/**
|
|
39
|
-
* Serializer for OTP request.
|
|
40
|
-
*
|
|
41
|
-
* Request model (no read-only fields).
|
|
42
|
-
*/
|
|
43
|
-
export interface OTPRequestRequest {
|
|
44
|
-
/** Email address for OTP delivery */
|
|
45
|
-
identifier: string;
|
|
46
|
-
/** Source URL for tracking registration (e.g., https://my.djangocfg.com) */
|
|
47
|
-
source_url?: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
25
|
/**
|
|
51
26
|
* OTP request response.
|
|
52
27
|
*
|
|
@@ -78,6 +53,31 @@ export interface OTPErrorResponse {
|
|
|
78
53
|
retry_after?: number | null;
|
|
79
54
|
}
|
|
80
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Serializer for OTP verification.
|
|
58
|
+
*
|
|
59
|
+
* Request model (no read-only fields).
|
|
60
|
+
*/
|
|
61
|
+
export interface OTPVerifyRequest {
|
|
62
|
+
/** Email address used for OTP request */
|
|
63
|
+
identifier: string;
|
|
64
|
+
otp: string;
|
|
65
|
+
/** Source URL for tracking login (e.g., https://my.djangocfg.com) */
|
|
66
|
+
source_url?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Serializer for OTP request.
|
|
71
|
+
*
|
|
72
|
+
* Request model (no read-only fields).
|
|
73
|
+
*/
|
|
74
|
+
export interface OTPRequestRequest {
|
|
75
|
+
/** Email address for OTP delivery */
|
|
76
|
+
identifier: string;
|
|
77
|
+
/** Source URL for tracking registration (e.g., https://my.djangocfg.com) */
|
|
78
|
+
source_url?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
81
|
/**
|
|
82
82
|
* Serializer for user details.
|
|
83
83
|
*
|
|
@@ -3,37 +3,15 @@
|
|
|
3
3
|
import * as Enums from "../enums";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Response model (includes read-only fields).
|
|
9
|
-
*/
|
|
10
|
-
export interface OAuthError {
|
|
11
|
-
/** Error code */
|
|
12
|
-
error: string;
|
|
13
|
-
/** Human-readable error description */
|
|
14
|
-
error_description?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Response with available OAuth providers.
|
|
19
|
-
*
|
|
20
|
-
* Response model (includes read-only fields).
|
|
21
|
-
*/
|
|
22
|
-
export interface OAuthProvidersResponse {
|
|
23
|
-
/** List of available OAuth providers */
|
|
24
|
-
providers: Array<Record<string, any>>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Response with OAuth authorization URL.
|
|
6
|
+
* Request to start OAuth flow.
|
|
29
7
|
*
|
|
30
|
-
*
|
|
8
|
+
* Request model (no read-only fields).
|
|
31
9
|
*/
|
|
32
|
-
export interface
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
|
|
10
|
+
export interface OAuthAuthorizeRequestRequest {
|
|
11
|
+
/** URL to redirect after OAuth authorization. If not provided, uses config's site_url + callback_path */
|
|
12
|
+
redirect_uri?: string;
|
|
13
|
+
/** Optional source URL for registration tracking */
|
|
14
|
+
source_url?: string;
|
|
37
15
|
}
|
|
38
16
|
|
|
39
17
|
/**
|
|
@@ -50,6 +28,33 @@ export interface OAuthCallbackRequestRequest {
|
|
|
50
28
|
redirect_uri?: string;
|
|
51
29
|
}
|
|
52
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Response with JWT tokens after OAuth authentication. When 2FA is required: -
|
|
33
|
+
* requires_2fa: True - session_id: UUID of 2FA verification session -
|
|
34
|
+
* access/refresh/user: null When 2FA is not required: - requires_2fa: False -
|
|
35
|
+
* session_id: null - access/refresh/user: populated
|
|
36
|
+
*
|
|
37
|
+
* Response model (includes read-only fields).
|
|
38
|
+
*/
|
|
39
|
+
export interface OAuthTokenResponse {
|
|
40
|
+
/** True if 2FA verification is required */
|
|
41
|
+
requires_2fa?: boolean;
|
|
42
|
+
/** 2FA session ID (only when requires_2fa=True) */
|
|
43
|
+
session_id?: string | null;
|
|
44
|
+
/** JWT access token (null when requires_2fa=True) */
|
|
45
|
+
access?: string | null;
|
|
46
|
+
/** JWT refresh token (null when requires_2fa=True) */
|
|
47
|
+
refresh?: string | null;
|
|
48
|
+
/** Authenticated user info (null when requires_2fa=True) */
|
|
49
|
+
user?: Record<string, any> | null;
|
|
50
|
+
/** True if a new user was created during this OAuth flow */
|
|
51
|
+
is_new_user: boolean;
|
|
52
|
+
/** True if a new OAuth connection was created */
|
|
53
|
+
is_new_connection: boolean;
|
|
54
|
+
/** True if user should be prompted to enable 2FA */
|
|
55
|
+
should_prompt_2fa?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
/**
|
|
54
59
|
* Serializer for OAuth connection info (user-facing).
|
|
55
60
|
*
|
|
@@ -75,42 +80,15 @@ export interface OAuthConnection {
|
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* Request model (no read-only fields).
|
|
81
|
-
*/
|
|
82
|
-
export interface OAuthAuthorizeRequestRequest {
|
|
83
|
-
/** URL to redirect after OAuth authorization. If not provided, uses config's site_url + callback_path */
|
|
84
|
-
redirect_uri?: string;
|
|
85
|
-
/** Optional source URL for registration tracking */
|
|
86
|
-
source_url?: string;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Response with JWT tokens after OAuth authentication. When 2FA is required: -
|
|
91
|
-
* requires_2fa: True - session_id: UUID of 2FA verification session -
|
|
92
|
-
* access/refresh/user: null When 2FA is not required: - requires_2fa: False -
|
|
93
|
-
* session_id: null - access/refresh/user: populated
|
|
83
|
+
* Response with OAuth authorization URL.
|
|
94
84
|
*
|
|
95
85
|
* Response model (includes read-only fields).
|
|
96
86
|
*/
|
|
97
|
-
export interface
|
|
98
|
-
/**
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
|
|
102
|
-
/** JWT access token (null when requires_2fa=True) */
|
|
103
|
-
access?: string | null;
|
|
104
|
-
/** JWT refresh token (null when requires_2fa=True) */
|
|
105
|
-
refresh?: string | null;
|
|
106
|
-
/** Authenticated user info (null when requires_2fa=True) */
|
|
107
|
-
user?: Record<string, any> | null;
|
|
108
|
-
/** True if a new user was created during this OAuth flow */
|
|
109
|
-
is_new_user: boolean;
|
|
110
|
-
/** True if a new OAuth connection was created */
|
|
111
|
-
is_new_connection: boolean;
|
|
112
|
-
/** True if user should be prompted to enable 2FA */
|
|
113
|
-
should_prompt_2fa?: boolean;
|
|
87
|
+
export interface OAuthAuthorizeResponse {
|
|
88
|
+
/** Full URL to redirect user to OAuth provider */
|
|
89
|
+
authorization_url: string;
|
|
90
|
+
/** State token for CSRF protection. Store this and verify on callback. */
|
|
91
|
+
state: string;
|
|
114
92
|
}
|
|
115
93
|
|
|
116
94
|
/**
|
|
@@ -125,3 +103,25 @@ export interface OAuthDisconnectRequestRequest {
|
|
|
125
103
|
provider: Enums.OAuthConnectionProvider;
|
|
126
104
|
}
|
|
127
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Response with available OAuth providers.
|
|
108
|
+
*
|
|
109
|
+
* Response model (includes read-only fields).
|
|
110
|
+
*/
|
|
111
|
+
export interface OAuthProvidersResponse {
|
|
112
|
+
/** List of available OAuth providers */
|
|
113
|
+
providers: Array<Record<string, any>>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Error response for OAuth endpoints.
|
|
118
|
+
*
|
|
119
|
+
* Response model (includes read-only fields).
|
|
120
|
+
*/
|
|
121
|
+
export interface OAuthError {
|
|
122
|
+
/** Error code */
|
|
123
|
+
error: string;
|
|
124
|
+
/** Human-readable error description */
|
|
125
|
+
error_description?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Request model (no read-only fields).
|
|
7
7
|
*/
|
|
8
|
-
export interface
|
|
8
|
+
export interface PatchedUserProfileUpdateRequest {
|
|
9
9
|
first_name?: string;
|
|
10
10
|
last_name?: string;
|
|
11
11
|
company?: string;
|
|
@@ -15,17 +15,24 @@ export interface UserProfileUpdateRequest {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Serializer for updating user profile.
|
|
19
18
|
*
|
|
20
19
|
* Request model (no read-only fields).
|
|
21
20
|
*/
|
|
22
|
-
export interface
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
export interface CfgAccountsProfileAvatarCreateRequest {
|
|
22
|
+
/** Avatar image file (JPEG, PNG, GIF, WebP, max 5MB) */
|
|
23
|
+
avatar: File | Blob;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Response serializer for account deletion.
|
|
28
|
+
*
|
|
29
|
+
* Response model (includes read-only fields).
|
|
30
|
+
*/
|
|
31
|
+
export interface AccountDeleteResponse {
|
|
32
|
+
/** Whether the account was successfully deleted */
|
|
33
|
+
success: boolean;
|
|
34
|
+
/** Human-readable message about the deletion */
|
|
35
|
+
message: string;
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
/**
|
|
@@ -60,24 +67,17 @@ export interface User {
|
|
|
60
67
|
}
|
|
61
68
|
|
|
62
69
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* Response model (includes read-only fields).
|
|
66
|
-
*/
|
|
67
|
-
export interface AccountDeleteResponse {
|
|
68
|
-
/** Whether the account was successfully deleted */
|
|
69
|
-
success: boolean;
|
|
70
|
-
/** Human-readable message about the deletion */
|
|
71
|
-
message: string;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
70
|
+
* Serializer for updating user profile.
|
|
75
71
|
*
|
|
76
72
|
* Request model (no read-only fields).
|
|
77
73
|
*/
|
|
78
|
-
export interface
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
export interface UserProfileUpdateRequest {
|
|
75
|
+
first_name?: string;
|
|
76
|
+
last_name?: string;
|
|
77
|
+
company?: string;
|
|
78
|
+
phone?: string;
|
|
79
|
+
position?: string;
|
|
80
|
+
language?: string;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/**
|
|
@@ -109,6 +109,7 @@ export class APIClient {
|
|
|
109
109
|
formData?: FormData;
|
|
110
110
|
binaryBody?: Blob | ArrayBuffer;
|
|
111
111
|
headers?: Record<string, string>;
|
|
112
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
112
113
|
}
|
|
113
114
|
): Promise<T> {
|
|
114
115
|
// Wrap request in retry logic if configured
|
|
@@ -146,6 +147,7 @@ export class APIClient {
|
|
|
146
147
|
formData?: FormData;
|
|
147
148
|
binaryBody?: Blob | ArrayBuffer;
|
|
148
149
|
headers?: Record<string, string>;
|
|
150
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
149
151
|
}
|
|
150
152
|
): Promise<T> {
|
|
151
153
|
// Build URL - handle both absolute and relative paths
|
|
@@ -195,6 +197,7 @@ export class APIClient {
|
|
|
195
197
|
body: options?.body,
|
|
196
198
|
formData: options?.formData,
|
|
197
199
|
binaryBody: options?.binaryBody,
|
|
200
|
+
responseType: options?.responseType,
|
|
198
201
|
});
|
|
199
202
|
|
|
200
203
|
const duration = Date.now() - startTime;
|
|
@@ -17,6 +17,11 @@ export interface HttpRequest {
|
|
|
17
17
|
formData?: FormData;
|
|
18
18
|
/** Binary data for octet-stream uploads */
|
|
19
19
|
binaryBody?: Blob | ArrayBuffer;
|
|
20
|
+
/**
|
|
21
|
+
* Force a specific response parser. When set, overrides Content-Type sniffing.
|
|
22
|
+
* Generated for endpoints whose primary response is binary (file downloads).
|
|
23
|
+
*/
|
|
24
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export interface HttpResponse<T = any> {
|
|
@@ -40,7 +45,7 @@ export interface HttpClientAdapter {
|
|
|
40
45
|
*/
|
|
41
46
|
export class FetchAdapter implements HttpClientAdapter {
|
|
42
47
|
async request<T = any>(request: HttpRequest): Promise<HttpResponse<T>> {
|
|
43
|
-
const { method, url, headers, body, params, formData, binaryBody } = request;
|
|
48
|
+
const { method, url, headers, body, params, formData, binaryBody, responseType } = request;
|
|
44
49
|
|
|
45
50
|
// Build URL with query params
|
|
46
51
|
let finalUrl = url;
|
|
@@ -85,14 +90,32 @@ export class FetchAdapter implements HttpClientAdapter {
|
|
|
85
90
|
credentials: 'include', // Include Django session cookies
|
|
86
91
|
});
|
|
87
92
|
|
|
88
|
-
// Parse response
|
|
93
|
+
// Parse response. Explicit `responseType` (set by the generator for binary
|
|
94
|
+
// endpoints) wins over Content-Type sniffing — backends often serve CSV/JSON
|
|
95
|
+
// file downloads with `text/csv` or `application/json`, which would otherwise
|
|
96
|
+
// be parsed as string/object instead of the Blob the caller expects.
|
|
97
|
+
//
|
|
98
|
+
// responseType set → use it directly
|
|
99
|
+
// application/json → JSON
|
|
100
|
+
// text/* → string
|
|
101
|
+
// anything else → Blob (file downloads, octet-stream, …)
|
|
89
102
|
let data: any = null;
|
|
90
|
-
const contentType = response.headers.get('content-type');
|
|
103
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
91
104
|
|
|
92
|
-
if (response.status !== 204
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
105
|
+
if (response.status !== 204) {
|
|
106
|
+
if (responseType === 'blob') {
|
|
107
|
+
data = await response.blob();
|
|
108
|
+
} else if (responseType === 'text') {
|
|
109
|
+
data = await response.text();
|
|
110
|
+
} else if (responseType === 'json') {
|
|
111
|
+
data = await response.json();
|
|
112
|
+
} else if (contentType.includes('application/json')) {
|
|
113
|
+
data = await response.json();
|
|
114
|
+
} else if (contentType.startsWith('text/')) {
|
|
115
|
+
data = await response.text();
|
|
116
|
+
} else {
|
|
117
|
+
data = await response.blob();
|
|
118
|
+
}
|
|
96
119
|
}
|
|
97
120
|
|
|
98
121
|
// Convert Headers to plain object
|
|
@@ -100,6 +100,7 @@ export class APIClient {
|
|
|
100
100
|
formData?: FormData;
|
|
101
101
|
binaryBody?: Blob | ArrayBuffer;
|
|
102
102
|
headers?: Record<string, string>;
|
|
103
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
103
104
|
}
|
|
104
105
|
): Promise<T> {
|
|
105
106
|
// Wrap request in retry logic if configured
|
|
@@ -137,6 +138,7 @@ export class APIClient {
|
|
|
137
138
|
formData?: FormData;
|
|
138
139
|
binaryBody?: Blob | ArrayBuffer;
|
|
139
140
|
headers?: Record<string, string>;
|
|
141
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
140
142
|
}
|
|
141
143
|
): Promise<T> {
|
|
142
144
|
// Build URL - handle both absolute and relative paths
|
|
@@ -186,6 +188,7 @@ export class APIClient {
|
|
|
186
188
|
body: options?.body,
|
|
187
189
|
formData: options?.formData,
|
|
188
190
|
binaryBody: options?.binaryBody,
|
|
191
|
+
responseType: options?.responseType,
|
|
189
192
|
});
|
|
190
193
|
|
|
191
194
|
const duration = Date.now() - startTime;
|
|
@@ -17,6 +17,11 @@ export interface HttpRequest {
|
|
|
17
17
|
formData?: FormData;
|
|
18
18
|
/** Binary data for octet-stream uploads */
|
|
19
19
|
binaryBody?: Blob | ArrayBuffer;
|
|
20
|
+
/**
|
|
21
|
+
* Force a specific response parser. When set, overrides Content-Type sniffing.
|
|
22
|
+
* Generated for endpoints whose primary response is binary (file downloads).
|
|
23
|
+
*/
|
|
24
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export interface HttpResponse<T = any> {
|
|
@@ -40,7 +45,7 @@ export interface HttpClientAdapter {
|
|
|
40
45
|
*/
|
|
41
46
|
export class FetchAdapter implements HttpClientAdapter {
|
|
42
47
|
async request<T = any>(request: HttpRequest): Promise<HttpResponse<T>> {
|
|
43
|
-
const { method, url, headers, body, params, formData, binaryBody } = request;
|
|
48
|
+
const { method, url, headers, body, params, formData, binaryBody, responseType } = request;
|
|
44
49
|
|
|
45
50
|
// Build URL with query params
|
|
46
51
|
let finalUrl = url;
|
|
@@ -85,14 +90,32 @@ export class FetchAdapter implements HttpClientAdapter {
|
|
|
85
90
|
credentials: 'include', // Include Django session cookies
|
|
86
91
|
});
|
|
87
92
|
|
|
88
|
-
// Parse response
|
|
93
|
+
// Parse response. Explicit `responseType` (set by the generator for binary
|
|
94
|
+
// endpoints) wins over Content-Type sniffing — backends often serve CSV/JSON
|
|
95
|
+
// file downloads with `text/csv` or `application/json`, which would otherwise
|
|
96
|
+
// be parsed as string/object instead of the Blob the caller expects.
|
|
97
|
+
//
|
|
98
|
+
// responseType set → use it directly
|
|
99
|
+
// application/json → JSON
|
|
100
|
+
// text/* → string
|
|
101
|
+
// anything else → Blob (file downloads, octet-stream, …)
|
|
89
102
|
let data: any = null;
|
|
90
|
-
const contentType = response.headers.get('content-type');
|
|
103
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
91
104
|
|
|
92
|
-
if (response.status !== 204
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
105
|
+
if (response.status !== 204) {
|
|
106
|
+
if (responseType === 'blob') {
|
|
107
|
+
data = await response.blob();
|
|
108
|
+
} else if (responseType === 'text') {
|
|
109
|
+
data = await response.text();
|
|
110
|
+
} else if (responseType === 'json') {
|
|
111
|
+
data = await response.json();
|
|
112
|
+
} else if (contentType.includes('application/json')) {
|
|
113
|
+
data = await response.json();
|
|
114
|
+
} else if (contentType.startsWith('text/')) {
|
|
115
|
+
data = await response.text();
|
|
116
|
+
} else {
|
|
117
|
+
data = await response.blob();
|
|
118
|
+
}
|
|
96
119
|
}
|
|
97
120
|
|
|
98
121
|
// Convert Headers to plain object
|
|
@@ -112,6 +112,7 @@ export class APIClient {
|
|
|
112
112
|
formData?: FormData;
|
|
113
113
|
binaryBody?: Blob | ArrayBuffer;
|
|
114
114
|
headers?: Record<string, string>;
|
|
115
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
115
116
|
}
|
|
116
117
|
): Promise<T> {
|
|
117
118
|
// Wrap request in retry logic if configured
|
|
@@ -149,6 +150,7 @@ export class APIClient {
|
|
|
149
150
|
formData?: FormData;
|
|
150
151
|
binaryBody?: Blob | ArrayBuffer;
|
|
151
152
|
headers?: Record<string, string>;
|
|
153
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
152
154
|
}
|
|
153
155
|
): Promise<T> {
|
|
154
156
|
// Build URL - handle both absolute and relative paths
|
|
@@ -198,6 +200,7 @@ export class APIClient {
|
|
|
198
200
|
body: options?.body,
|
|
199
201
|
formData: options?.formData,
|
|
200
202
|
binaryBody: options?.binaryBody,
|
|
203
|
+
responseType: options?.responseType,
|
|
201
204
|
});
|
|
202
205
|
|
|
203
206
|
const duration = Date.now() - startTime;
|
|
@@ -17,6 +17,11 @@ export interface HttpRequest {
|
|
|
17
17
|
formData?: FormData;
|
|
18
18
|
/** Binary data for octet-stream uploads */
|
|
19
19
|
binaryBody?: Blob | ArrayBuffer;
|
|
20
|
+
/**
|
|
21
|
+
* Force a specific response parser. When set, overrides Content-Type sniffing.
|
|
22
|
+
* Generated for endpoints whose primary response is binary (file downloads).
|
|
23
|
+
*/
|
|
24
|
+
responseType?: 'json' | 'text' | 'blob';
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export interface HttpResponse<T = any> {
|
|
@@ -40,7 +45,7 @@ export interface HttpClientAdapter {
|
|
|
40
45
|
*/
|
|
41
46
|
export class FetchAdapter implements HttpClientAdapter {
|
|
42
47
|
async request<T = any>(request: HttpRequest): Promise<HttpResponse<T>> {
|
|
43
|
-
const { method, url, headers, body, params, formData, binaryBody } = request;
|
|
48
|
+
const { method, url, headers, body, params, formData, binaryBody, responseType } = request;
|
|
44
49
|
|
|
45
50
|
// Build URL with query params
|
|
46
51
|
let finalUrl = url;
|
|
@@ -85,14 +90,32 @@ export class FetchAdapter implements HttpClientAdapter {
|
|
|
85
90
|
credentials: 'include', // Include Django session cookies
|
|
86
91
|
});
|
|
87
92
|
|
|
88
|
-
// Parse response
|
|
93
|
+
// Parse response. Explicit `responseType` (set by the generator for binary
|
|
94
|
+
// endpoints) wins over Content-Type sniffing — backends often serve CSV/JSON
|
|
95
|
+
// file downloads with `text/csv` or `application/json`, which would otherwise
|
|
96
|
+
// be parsed as string/object instead of the Blob the caller expects.
|
|
97
|
+
//
|
|
98
|
+
// responseType set → use it directly
|
|
99
|
+
// application/json → JSON
|
|
100
|
+
// text/* → string
|
|
101
|
+
// anything else → Blob (file downloads, octet-stream, …)
|
|
89
102
|
let data: any = null;
|
|
90
|
-
const contentType = response.headers.get('content-type');
|
|
103
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
91
104
|
|
|
92
|
-
if (response.status !== 204
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
105
|
+
if (response.status !== 204) {
|
|
106
|
+
if (responseType === 'blob') {
|
|
107
|
+
data = await response.blob();
|
|
108
|
+
} else if (responseType === 'text') {
|
|
109
|
+
data = await response.text();
|
|
110
|
+
} else if (responseType === 'json') {
|
|
111
|
+
data = await response.json();
|
|
112
|
+
} else if (contentType.includes('application/json')) {
|
|
113
|
+
data = await response.json();
|
|
114
|
+
} else if (contentType.startsWith('text/')) {
|
|
115
|
+
data = await response.text();
|
|
116
|
+
} else {
|
|
117
|
+
data = await response.blob();
|
|
118
|
+
}
|
|
96
119
|
}
|
|
97
120
|
|
|
98
121
|
// Convert Headers to plain object
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Auto-generated by DjangoCFG - see CLAUDE.md
|
|
3
|
-
/**
|
|
4
|
-
* Serializer for regenerating backup codes.
|
|
5
|
-
*
|
|
6
|
-
* Request model (no read-only fields).
|
|
7
|
-
*/
|
|
8
|
-
export interface BackupCodesRegenerateRequest {
|
|
9
|
-
/** TOTP code for verification */
|
|
10
|
-
code: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
3
|
/**
|
|
14
4
|
* Response serializer for backup codes regeneration.
|
|
15
5
|
*
|
|
@@ -36,3 +26,13 @@ export interface BackupCodesStatus {
|
|
|
36
26
|
warning?: string | null;
|
|
37
27
|
}
|
|
38
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Serializer for regenerating backup codes.
|
|
31
|
+
*
|
|
32
|
+
* Request model (no read-only fields).
|
|
33
|
+
*/
|
|
34
|
+
export interface BackupCodesRegenerateRequest {
|
|
35
|
+
/** TOTP code for verification */
|
|
36
|
+
code: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
@@ -2,16 +2,6 @@
|
|
|
2
2
|
// Auto-generated by DjangoCFG - see CLAUDE.md
|
|
3
3
|
import * as Enums from "../enums";
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Response serializer for device list endpoint.
|
|
7
|
-
*
|
|
8
|
-
* Response model (includes read-only fields).
|
|
9
|
-
*/
|
|
10
|
-
export interface DeviceListResponse {
|
|
11
|
-
devices: Array<DeviceList>;
|
|
12
|
-
has_2fa_enabled: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
5
|
/**
|
|
16
6
|
* Serializer for completely disabling 2FA.
|
|
17
7
|
*
|
|
@@ -22,6 +12,16 @@ export interface DisableRequest {
|
|
|
22
12
|
code: string;
|
|
23
13
|
}
|
|
24
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Response serializer for device list endpoint.
|
|
17
|
+
*
|
|
18
|
+
* Response model (includes read-only fields).
|
|
19
|
+
*/
|
|
20
|
+
export interface DeviceListResponse {
|
|
21
|
+
devices: Array<DeviceList>;
|
|
22
|
+
has_2fa_enabled: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
25
|
/**
|
|
26
26
|
* Serializer for listing TOTP devices.
|
|
27
27
|
*
|
|
@@ -12,24 +12,6 @@ export interface ConfirmSetupRequest {
|
|
|
12
12
|
code: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
* Response serializer for setup initiation.
|
|
17
|
-
*
|
|
18
|
-
* Response model (includes read-only fields).
|
|
19
|
-
*/
|
|
20
|
-
export interface SetupResponse {
|
|
21
|
-
/** Device ID to use for confirmation */
|
|
22
|
-
device_id: string;
|
|
23
|
-
/** Base32-encoded TOTP secret (for manual entry) */
|
|
24
|
-
secret: string;
|
|
25
|
-
/** otpauth:// URI for QR code generation */
|
|
26
|
-
provisioning_uri: string;
|
|
27
|
-
/** Base64-encoded QR code image (data URI) */
|
|
28
|
-
qr_code_base64: string;
|
|
29
|
-
/** Seconds until setup expires (typically 600 = 10 minutes) */
|
|
30
|
-
expires_in: number;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
15
|
/**
|
|
34
16
|
* Serializer for starting 2FA setup.
|
|
35
17
|
*
|
|
@@ -53,3 +35,21 @@ export interface ConfirmSetupResponse {
|
|
|
53
35
|
backup_codes_warning: string;
|
|
54
36
|
}
|
|
55
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Response serializer for setup initiation.
|
|
40
|
+
*
|
|
41
|
+
* Response model (includes read-only fields).
|
|
42
|
+
*/
|
|
43
|
+
export interface SetupResponse {
|
|
44
|
+
/** Device ID to use for confirmation */
|
|
45
|
+
device_id: string;
|
|
46
|
+
/** Base32-encoded TOTP secret (for manual entry) */
|
|
47
|
+
secret: string;
|
|
48
|
+
/** otpauth:// URI for QR code generation */
|
|
49
|
+
provisioning_uri: string;
|
|
50
|
+
/** Base64-encoded QR code image (data URI) */
|
|
51
|
+
qr_code_base64: string;
|
|
52
|
+
/** Seconds until setup expires (typically 600 = 10 minutes) */
|
|
53
|
+
expires_in: number;
|
|
54
|
+
}
|
|
55
|
+
|