@djangocfg/api 2.1.99 → 2.1.101

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 (41) hide show
  1. package/dist/auth-server.cjs +333 -313
  2. package/dist/auth-server.cjs.map +1 -1
  3. package/dist/auth-server.mjs +333 -313
  4. package/dist/auth-server.mjs.map +1 -1
  5. package/dist/auth.cjs +471 -386
  6. package/dist/auth.cjs.map +1 -1
  7. package/dist/auth.d.cts +42 -1
  8. package/dist/auth.d.ts +42 -1
  9. package/dist/auth.mjs +471 -386
  10. package/dist/auth.mjs.map +1 -1
  11. package/dist/clients.cjs +458 -383
  12. package/dist/clients.cjs.map +1 -1
  13. package/dist/clients.d.cts +55 -1
  14. package/dist/clients.d.ts +55 -1
  15. package/dist/clients.mjs +458 -383
  16. package/dist/clients.mjs.map +1 -1
  17. package/dist/hooks.cjs +184 -111
  18. package/dist/hooks.cjs.map +1 -1
  19. package/dist/hooks.d.cts +48 -1
  20. package/dist/hooks.d.ts +48 -1
  21. package/dist/hooks.mjs +184 -111
  22. package/dist/hooks.mjs.map +1 -1
  23. package/dist/index.cjs +382 -313
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +58 -5
  26. package/dist/index.d.ts +58 -5
  27. package/dist/index.mjs +382 -313
  28. package/dist/index.mjs.map +1 -1
  29. package/package.json +3 -3
  30. package/src/auth/context/AuthContext.tsx +31 -0
  31. package/src/auth/context/types.ts +4 -0
  32. package/src/auth/hooks/index.ts +7 -0
  33. package/src/auth/hooks/useDeleteAccount.ts +90 -0
  34. package/src/generated/cfg_accounts/CLAUDE.md +4 -3
  35. package/src/generated/cfg_accounts/_utils/fetchers/accounts__user_profile.ts +58 -0
  36. package/src/generated/cfg_accounts/_utils/hooks/accounts__user_profile.ts +19 -0
  37. package/src/generated/cfg_accounts/_utils/schemas/AccountDeleteResponse.schema.ts +20 -0
  38. package/src/generated/cfg_accounts/_utils/schemas/index.ts +1 -0
  39. package/src/generated/cfg_accounts/accounts__user_profile/client.ts +14 -0
  40. package/src/generated/cfg_accounts/accounts__user_profile/models.ts +12 -0
  41. package/src/generated/cfg_accounts/schema.json +69 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/api",
3
- "version": "2.1.99",
3
+ "version": "2.1.101",
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",
@@ -74,7 +74,7 @@
74
74
  "check": "tsc --noEmit"
75
75
  },
76
76
  "peerDependencies": {
77
- "@djangocfg/ui-nextjs": "^2.1.99",
77
+ "@djangocfg/ui-nextjs": "^2.1.101",
78
78
  "consola": "^3.4.2",
79
79
  "next": ">=16.0.0",
80
80
  "p-retry": "^7.0.0",
@@ -85,7 +85,7 @@
85
85
  "devDependencies": {
86
86
  "@types/node": "^24.7.2",
87
87
  "@types/react": "^19.0.0",
88
- "@djangocfg/typescript-config": "^2.1.99",
88
+ "@djangocfg/typescript-config": "^2.1.101",
89
89
  "next": "^16.0.0",
90
90
  "react": "^19.0.0",
91
91
  "tsup": "^8.5.0",
@@ -553,6 +553,24 @@ const AuthProviderInternal: React.FC<AuthProviderProps> = ({ children, config })
553
553
  return Boolean(user?.is_staff || user?.is_superuser);
554
554
  }, [user]);
555
555
 
556
+ // Profile management: Update profile data
557
+ const updateProfile = useCallback(
558
+ async (data: { first_name?: string; last_name?: string; username?: string }): Promise<UserProfile> => {
559
+ const result = await accounts.partialUpdateProfile(data);
560
+ return result as UserProfile;
561
+ },
562
+ [accounts]
563
+ );
564
+
565
+ // Profile management: Upload avatar
566
+ const uploadAvatar = useCallback(
567
+ async (avatar: File | Blob): Promise<UserProfile> => {
568
+ const result = await accounts.uploadAvatar(avatar);
569
+ return result as UserProfile;
570
+ },
571
+ [accounts]
572
+ );
573
+
556
574
  // Memoized context value
557
575
  const value = useMemo<AuthContextType>(
558
576
  () => ({
@@ -580,6 +598,9 @@ const AuthProviderInternal: React.FC<AuthProviderProps> = ({ children, config })
580
598
  getRedirectUrl: redirectManager.getFinalRedirectUrl,
581
599
  clearRedirectUrl: redirectManager.clearRedirect,
582
600
  hasRedirectUrl: redirectManager.hasRedirect,
601
+ // Profile management
602
+ updateProfile,
603
+ uploadAvatar,
583
604
  }),
584
605
  [
585
606
  user,
@@ -598,6 +619,8 @@ const AuthProviderInternal: React.FC<AuthProviderProps> = ({ children, config })
598
619
  refreshToken,
599
620
  logout,
600
621
  redirectManager,
622
+ updateProfile,
623
+ uploadAvatar,
601
624
  ],
602
625
  );
603
626
 
@@ -661,6 +684,14 @@ const defaultAuthState: AuthContextType = {
661
684
  getRedirectUrl: () => null,
662
685
  clearRedirectUrl: () => {},
663
686
  hasRedirectUrl: () => false,
687
+ updateProfile: async () => {
688
+ authLogger.warn('useAuth: updateProfile called outside AuthProvider');
689
+ return {} as UserProfile;
690
+ },
691
+ uploadAvatar: async () => {
692
+ authLogger.warn('useAuth: uploadAvatar called outside AuthProvider');
693
+ return {} as UserProfile;
694
+ },
664
695
  };
665
696
 
666
697
  /**
@@ -64,6 +64,10 @@ export interface AuthContextType {
64
64
  getRedirectUrl: () => string;
65
65
  clearRedirectUrl: () => void;
66
66
  hasRedirectUrl: () => boolean;
67
+
68
+ // Profile Management Methods
69
+ updateProfile: (data: { first_name?: string; last_name?: string; username?: string }) => Promise<UserProfile>;
70
+ uploadAvatar: (avatar: File | Blob) => Promise<UserProfile>;
67
71
  }
68
72
 
69
73
  // Provider props
@@ -48,3 +48,10 @@ export {
48
48
 
49
49
  // Token refresh
50
50
  export { useTokenRefresh } from './useTokenRefresh';
51
+
52
+ // Account deletion
53
+ export {
54
+ useDeleteAccount,
55
+ type UseDeleteAccountReturn,
56
+ type DeleteAccountResult,
57
+ } from './useDeleteAccount';
@@ -0,0 +1,90 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useState } from 'react';
4
+
5
+ import { apiAccounts } from '../../clients';
6
+ import { authLogger } from '../utils/logger';
7
+ import { useAuth } from '../context';
8
+
9
+ export interface DeleteAccountResult {
10
+ success: boolean;
11
+ message: string;
12
+ }
13
+
14
+ export interface UseDeleteAccountReturn {
15
+ /** Loading state */
16
+ isLoading: boolean;
17
+ /** Error message */
18
+ error: string | null;
19
+ /** Delete the account */
20
+ deleteAccount: () => Promise<DeleteAccountResult>;
21
+ /** Clear error */
22
+ clearError: () => void;
23
+ }
24
+
25
+ /**
26
+ * Hook for deleting user account.
27
+ *
28
+ * This performs a soft delete - deactivates the account and anonymizes personal data.
29
+ * The account can be restored by an administrator if needed.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * const { deleteAccount, isLoading, error } = useDeleteAccount();
34
+ *
35
+ * const handleDelete = async () => {
36
+ * const result = await deleteAccount();
37
+ * if (result.success) {
38
+ * // Account deleted, perform logout
39
+ * await logout();
40
+ * }
41
+ * };
42
+ * ```
43
+ */
44
+ export const useDeleteAccount = (): UseDeleteAccountReturn => {
45
+ const [isLoading, setIsLoading] = useState(false);
46
+ const [error, setError] = useState<string | null>(null);
47
+ const { logout } = useAuth();
48
+
49
+ const clearError = useCallback(() => {
50
+ setError(null);
51
+ }, []);
52
+
53
+ /**
54
+ * Delete the user account (soft delete)
55
+ */
56
+ const deleteAccount = useCallback(async (): Promise<DeleteAccountResult> => {
57
+ setIsLoading(true);
58
+ setError(null);
59
+
60
+ try {
61
+ authLogger.info('Deleting account...');
62
+
63
+ const response = await apiAccounts.user_profile.accountsProfileDeleteCreate();
64
+
65
+ if (!response.success) {
66
+ authLogger.error('Failed to delete account:', response.message);
67
+ setError(response.message);
68
+ throw new Error(response.message);
69
+ }
70
+
71
+ } catch (error) {
72
+ authLogger.error('Failed to delete account:', error);
73
+ throw error;
74
+ } finally {
75
+ setIsLoading(false);
76
+ }
77
+
78
+ // Return success response
79
+
80
+ await logout();
81
+ return { success: true, message: 'Account deleted successfully' };
82
+ }, []);
83
+
84
+ return {
85
+ isLoading,
86
+ error,
87
+ deleteAccount,
88
+ clearError,
89
+ };
90
+ };
@@ -11,14 +11,14 @@ python manage.py generate_client --groups cfg_accounts --typescript
11
11
  | | |
12
12
  |---|---|
13
13
  | Version | 3.0.3 |
14
- | Operations | 14 |
15
- | Schemas | 20 |
14
+ | Operations | 15 |
15
+ | Schemas | 21 |
16
16
 
17
17
  ## Resources
18
18
 
19
19
  - **Auth** (1 ops)
20
20
  - **OAuth** (5 ops)
21
- - **User Profile** (6 ops)
21
+ - **User Profile** (7 ops)
22
22
  - **accounts** (2 ops)
23
23
 
24
24
  ## Operations
@@ -35,6 +35,7 @@ python manage.py generate_client --groups cfg_accounts --typescript
35
35
 
36
36
  **User Profile:**
37
37
  - `POST` /cfg/accounts/profile/avatar/ → `cfg_accounts_profile_avatar_create`
38
+ - `POST` /cfg/accounts/profile/delete/ → `cfg_accounts_profile_delete_create`
38
39
  - `PATCH` /cfg/accounts/profile/partial/ → `cfg_accounts_profile_partial_partial_update`
39
40
  - `PUT` /cfg/accounts/profile/partial/ → `cfg_accounts_profile_partial_update`
40
41
  - `GET` /cfg/accounts/profile/ → `cfg_accounts_profile_retrieve`
@@ -31,6 +31,7 @@
31
31
  * ```
32
32
  */
33
33
  import { consola } from 'consola'
34
+ import { AccountDeleteResponseSchema, type AccountDeleteResponse } from '../schemas/AccountDeleteResponse.schema'
34
35
  import { CfgAccountsProfileAvatarCreateRequestSchema, type CfgAccountsProfileAvatarCreateRequest } from '../schemas/CfgAccountsProfileAvatarCreateRequest.schema'
35
36
  import { PatchedUserProfileUpdateRequestSchema, type PatchedUserProfileUpdateRequest } from '../schemas/PatchedUserProfileUpdateRequest.schema'
36
37
  import { UserSchema, type User } from '../schemas/User.schema'
@@ -151,6 +152,63 @@ export async function createAccountsProfileAvatarCreate( data: CfgAccountsProfi
151
152
  }
152
153
 
153
154
 
155
+ /**
156
+ * Delete user account
157
+ *
158
+ * @method POST
159
+ * @path /cfg/accounts/profile/delete/
160
+ */
161
+ export async function createAccountsProfileDeleteCreate( client?: any
162
+ ): Promise<AccountDeleteResponse> {
163
+ const api = client || getAPIInstance()
164
+ const response = await api.user_profile.accountsProfileDeleteCreate()
165
+ try {
166
+ return AccountDeleteResponseSchema.parse(response)
167
+ } catch (error) {
168
+ // Zod validation error - log detailed information
169
+ consola.error('❌ Zod Validation Failed');
170
+ consola.box(`createAccountsProfileDeleteCreate\nPath: /cfg/accounts/profile/delete/\nMethod: POST`);
171
+
172
+ if (error instanceof Error && 'issues' in error && Array.isArray((error as any).issues)) {
173
+ consola.error('Validation Issues:');
174
+ (error as any).issues.forEach((issue: any, index: number) => {
175
+ consola.error(` ${index + 1}. ${issue.path.join('.') || 'root'}`);
176
+ consola.error(` ├─ Message: ${issue.message}`);
177
+ if (issue.expected) consola.error(` ├─ Expected: ${issue.expected}`);
178
+ if (issue.received) consola.error(` └─ Received: ${issue.received}`);
179
+ });
180
+ }
181
+
182
+ consola.error('Response data:', response);
183
+
184
+ // Dispatch browser CustomEvent (only if window is defined)
185
+ if (typeof window !== 'undefined' && error instanceof Error && 'issues' in error) {
186
+ try {
187
+ const event = new CustomEvent('zod-validation-error', {
188
+ detail: {
189
+ operation: 'createAccountsProfileDeleteCreate',
190
+ path: '/cfg/accounts/profile/delete/',
191
+ method: 'POST',
192
+ error: error,
193
+ response: response,
194
+ timestamp: new Date(),
195
+ },
196
+ bubbles: true,
197
+ cancelable: false,
198
+ });
199
+ window.dispatchEvent(event);
200
+ } catch (eventError) {
201
+ // Silently fail - event dispatch should never crash the app
202
+ consola.warn('Failed to dispatch validation error event:', eventError);
203
+ }
204
+ }
205
+
206
+ // Re-throw the error
207
+ throw error;
208
+ }
209
+ }
210
+
211
+
154
212
  /**
155
213
  * Partial update user profile
156
214
  *
@@ -21,6 +21,7 @@ import useSWR from 'swr'
21
21
  import { useSWRConfig } from 'swr'
22
22
  import * as Fetchers from '../fetchers/accounts__user_profile'
23
23
  import type { API } from '../../index'
24
+ import type { AccountDeleteResponse } from '../schemas/AccountDeleteResponse.schema'
24
25
  import type { CfgAccountsProfileAvatarCreateRequest } from '../schemas/CfgAccountsProfileAvatarCreateRequest.schema'
25
26
  import type { PatchedUserProfileUpdateRequest } from '../schemas/PatchedUserProfileUpdateRequest.schema'
26
27
  import type { User } from '../schemas/User.schema'
@@ -58,6 +59,24 @@ export function useCreateAccountsProfileAvatarCreate() {
58
59
  }
59
60
 
60
61
 
62
+ /**
63
+ * Delete user account
64
+ *
65
+ * @method POST
66
+ * @path /cfg/accounts/profile/delete/
67
+ */
68
+ export function useCreateAccountsProfileDeleteCreate() {
69
+ const { mutate } = useSWRConfig()
70
+
71
+ return async (client?: API): Promise<AccountDeleteResponse> => {
72
+ const result = await Fetchers.createAccountsProfileDeleteCreate(client)
73
+ // Revalidate related queries
74
+ mutate('cfg-accounts-profile-delete')
75
+ return result
76
+ }
77
+ }
78
+
79
+
61
80
  /**
62
81
  * Partial update user profile
63
82
  *
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Zod schema for AccountDeleteResponse
3
+ *
4
+ * This schema provides runtime validation and type inference.
5
+ * * Response serializer for account deletion.
6
+ * */
7
+ import { z } from 'zod'
8
+
9
+ /**
10
+ * Response serializer for account deletion.
11
+ */
12
+ export const AccountDeleteResponseSchema = z.object({
13
+ success: z.boolean(),
14
+ message: z.string(),
15
+ })
16
+
17
+ /**
18
+ * Infer TypeScript type from Zod schema
19
+ */
20
+ export type AccountDeleteResponse = z.infer<typeof AccountDeleteResponseSchema>
@@ -17,6 +17,7 @@
17
17
  * ```
18
18
  */
19
19
 
20
+ export * from './AccountDeleteResponse.schema'
20
21
  export * from './CentrifugoToken.schema'
21
22
  export * from './CfgAccountsProfileAvatarCreateRequest.schema'
22
23
  export * from './OAuthAuthorizeRequestRequest.schema'
@@ -34,6 +34,20 @@ export class UserProfile {
34
34
  return response;
35
35
  }
36
36
 
37
+ /**
38
+ * Delete user account
39
+ *
40
+ * Permanently delete the current user's account. This operation: -
41
+ * Deactivates the account (user cannot log in) - Anonymizes personal data
42
+ * (GDPR compliance) - Frees up the email address for re-registration -
43
+ * Preserves audit trail The account can be restored by an administrator if
44
+ * needed.
45
+ */
46
+ async accountsProfileDeleteCreate(): Promise<Models.AccountDeleteResponse> {
47
+ const response = await this.client.request('POST', "/cfg/accounts/profile/delete/");
48
+ return response;
49
+ }
50
+
37
51
  /**
38
52
  * Partial update user profile
39
53
  *
@@ -38,6 +38,18 @@ export interface CfgAccountsProfileAvatarCreateRequest {
38
38
  avatar: File | Blob;
39
39
  }
40
40
 
41
+ /**
42
+ * Response serializer for account deletion.
43
+ *
44
+ * Response model (includes read-only fields).
45
+ */
46
+ export interface AccountDeleteResponse {
47
+ /** Whether the account was successfully deleted */
48
+ success: boolean;
49
+ /** Human-readable message about the deletion */
50
+ message: string;
51
+ }
52
+
41
53
  /**
42
54
  * Serializer for updating user profile.
43
55
  *
@@ -499,6 +499,57 @@
499
499
  "x-async-capable": false
500
500
  }
501
501
  },
502
+ "/cfg/accounts/profile/delete/": {
503
+ "post": {
504
+ "operationId": "cfg_accounts_profile_delete_create",
505
+ "description": "\n Permanently delete the current user's account.\n\n This operation:\n - Deactivates the account (user cannot log in)\n - Anonymizes personal data (GDPR compliance)\n - Frees up the email address for re-registration\n - Preserves audit trail\n\n The account can be restored by an administrator if needed.\n ",
506
+ "summary": "Delete user account",
507
+ "tags": [
508
+ "User Profile"
509
+ ],
510
+ "security": [
511
+ {
512
+ "jwtAuth": []
513
+ },
514
+ {
515
+ "cookieAuth": []
516
+ }
517
+ ],
518
+ "responses": {
519
+ "200": {
520
+ "content": {
521
+ "application/json": {
522
+ "schema": {
523
+ "$ref": "#/components/schemas/AccountDeleteResponse"
524
+ }
525
+ }
526
+ },
527
+ "description": ""
528
+ },
529
+ "401": {
530
+ "content": {
531
+ "application/json": {
532
+ "schema": {
533
+ "description": "Authentication credentials were not provided."
534
+ }
535
+ }
536
+ },
537
+ "description": ""
538
+ },
539
+ "400": {
540
+ "content": {
541
+ "application/json": {
542
+ "schema": {
543
+ "description": "Account is already deleted."
544
+ }
545
+ }
546
+ },
547
+ "description": ""
548
+ }
549
+ },
550
+ "x-async-capable": false
551
+ }
552
+ },
502
553
  "/cfg/accounts/profile/partial/": {
503
554
  "put": {
504
555
  "operationId": "cfg_accounts_profile_partial_update",
@@ -868,6 +919,24 @@
868
919
  },
869
920
  "components": {
870
921
  "schemas": {
922
+ "AccountDeleteResponse": {
923
+ "type": "object",
924
+ "description": "Response serializer for account deletion.",
925
+ "properties": {
926
+ "success": {
927
+ "type": "boolean",
928
+ "description": "Whether the account was successfully deleted"
929
+ },
930
+ "message": {
931
+ "type": "string",
932
+ "description": "Human-readable message about the deletion"
933
+ }
934
+ },
935
+ "required": [
936
+ "message",
937
+ "success"
938
+ ]
939
+ },
871
940
  "CentrifugoToken": {
872
941
  "type": "object",
873
942
  "description": "Nested serializer for Centrifugo WebSocket connection token.",