@djangocfg/api 2.1.127 → 2.1.130

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 (51) hide show
  1. package/dist/auth-server.cjs +10 -19
  2. package/dist/auth-server.cjs.map +1 -1
  3. package/dist/auth-server.mjs +10 -19
  4. package/dist/auth-server.mjs.map +1 -1
  5. package/dist/auth.cjs +35 -48
  6. package/dist/auth.cjs.map +1 -1
  7. package/dist/auth.d.cts +11 -17
  8. package/dist/auth.d.ts +11 -17
  9. package/dist/auth.mjs +35 -48
  10. package/dist/auth.mjs.map +1 -1
  11. package/dist/clients.cjs +20 -31
  12. package/dist/clients.cjs.map +1 -1
  13. package/dist/clients.d.cts +46 -54
  14. package/dist/clients.d.ts +46 -54
  15. package/dist/clients.mjs +20 -31
  16. package/dist/clients.mjs.map +1 -1
  17. package/dist/hooks.cjs +8 -17
  18. package/dist/hooks.cjs.map +1 -1
  19. package/dist/hooks.d.cts +11 -20
  20. package/dist/hooks.d.ts +11 -20
  21. package/dist/hooks.mjs +8 -17
  22. package/dist/hooks.mjs.map +1 -1
  23. package/dist/index.cjs +12 -23
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +15 -35
  26. package/dist/index.d.ts +15 -35
  27. package/dist/index.mjs +12 -23
  28. package/dist/index.mjs.map +1 -1
  29. package/package.json +2 -2
  30. package/src/auth/context/AccountsContext.tsx +23 -28
  31. package/src/auth/context/AuthContext.tsx +2 -2
  32. package/src/generated/cfg_accounts/_utils/schemas/CentrifugoToken.schema.ts +1 -1
  33. package/src/generated/cfg_accounts/_utils/schemas/OAuthConnection.schema.ts +2 -2
  34. package/src/generated/cfg_accounts/_utils/schemas/OAuthDisconnectRequestRequest.schema.ts +1 -1
  35. package/src/generated/cfg_accounts/_utils/schemas/OTPVerifyRequest.schema.ts +1 -1
  36. package/src/generated/cfg_accounts/_utils/schemas/User.schema.ts +2 -2
  37. package/src/generated/cfg_accounts/accounts/models.ts +1 -1
  38. package/src/generated/cfg_accounts/accounts__oauth/client.ts +1 -1
  39. package/src/generated/cfg_accounts/accounts__oauth/models.ts +1 -1
  40. package/src/generated/cfg_accounts/enums.ts +1 -19
  41. package/src/generated/cfg_centrifugo/_utils/fetchers/centrifugo__centrifugo_monitoring.ts +2 -2
  42. package/src/generated/cfg_centrifugo/_utils/hooks/centrifugo__centrifugo_monitoring.ts +1 -1
  43. package/src/generated/cfg_centrifugo/_utils/schemas/Publish.schema.ts +2 -2
  44. package/src/generated/cfg_centrifugo/centrifugo__centrifugo_monitoring/client.ts +3 -3
  45. package/src/generated/cfg_centrifugo/schema.json +18 -0
  46. package/src/generated/cfg_totp/_utils/fetchers/totp__totp_management.ts +2 -2
  47. package/src/generated/cfg_totp/_utils/hooks/totp__totp_management.ts +1 -1
  48. package/src/generated/cfg_totp/_utils/schemas/DeviceList.schema.ts +3 -3
  49. package/src/generated/cfg_totp/_utils/schemas/TotpVerifyUser.schema.ts +2 -2
  50. package/src/generated/cfg_totp/schema.json +18 -0
  51. package/src/generated/cfg_totp/totp__totp_management/client.ts +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/api",
3
- "version": "2.1.127",
3
+ "version": "2.1.130",
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.0.0",
87
- "@djangocfg/typescript-config": "^2.1.127",
87
+ "@djangocfg/typescript-config": "^2.1.130",
88
88
  "next": "^16.0.0",
89
89
  "react": "^19.0.0",
90
90
  "tsup": "^8.5.0",
@@ -60,7 +60,7 @@ export interface AccountsContextValue {
60
60
  updateProfile: (data: UserProfileUpdateRequest) => Promise<User>;
61
61
  partialUpdateProfile: (data: PatchedUserProfileUpdateRequest) => Promise<User>;
62
62
  uploadAvatar: (avatar: File | Blob) => Promise<User>;
63
- refreshProfile: (callerId?: string) => Promise<User | undefined>;
63
+ refreshProfile: (options?: { callerId?: string; force?: boolean }) => Promise<User | undefined>;
64
64
 
65
65
  // Authentication
66
66
  requestOTP: (data: OTPRequestRequest) => Promise<OTPRequestResponse>;
@@ -114,30 +114,25 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
114
114
  const otpVerifyMutation = useCreateAccountsOtpVerifyCreate();
115
115
  const tokenRefreshMutation = useCreateAccountsTokenRefreshCreate();
116
116
 
117
- // Refresh profile - fetch and cache with stable callback
118
- const refreshProfile = useCallback(async (callerId?: string): Promise<User | undefined> => {
119
- // Use refs to check current state without creating dependency
120
- const currentProfile = profileRef.current;
117
+ // Refresh profile - fetch from API and update cache
118
+ const refreshProfile = useCallback(async (options?: { callerId?: string; force?: boolean }): Promise<User | undefined> => {
119
+ const { callerId, force } = options || {};
121
120
  const currentLoading = isLoadingRef.current;
122
121
 
123
- // Prevent duplicate calls if profile is already loaded and not loading
124
- if (currentProfile && !currentLoading) {
125
- authLogger.debug(`Profile already loaded, returning cached (caller: ${callerId})`);
126
- return currentProfile;
122
+ // Prevent duplicate concurrent calls
123
+ if (currentLoading) {
124
+ authLogger.debug(`Profile loading in progress, skipping (caller: ${callerId})`);
125
+ return profileRef.current;
127
126
  }
128
127
 
129
128
  setIsLoadingProfile(true);
130
129
  isLoadingRef.current = true;
131
130
  setProfileError(null);
132
131
  try {
133
- // Log caller for debugging excessive API calls using consola logger
134
- if (callerId) {
135
- authLogger.debug(`Profile refresh called by: ${callerId}`);
136
- }
132
+ authLogger.debug(`Fetching profile from API (caller: ${callerId}, force: ${force})`);
137
133
  const result = await getAccountsProfileRetrieve(apiAccounts);
138
134
  setProfile(result);
139
135
  profileRef.current = result;
140
- // Save to cache with 1 hour TTL
141
136
  setCachedProfile(result);
142
137
  return result;
143
138
  } catch (error) {
@@ -148,27 +143,27 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
148
143
  setIsLoadingProfile(false);
149
144
  isLoadingRef.current = false;
150
145
  }
151
- }, []); // Empty dependencies - callback is stable
146
+ }, []);
152
147
 
153
- // Update profile (full)
148
+ // Update profile (full) - then reload from API
154
149
  const updateProfile = async (data: UserProfileUpdateRequest): Promise<User> => {
155
- const result = await updateMutation(data, apiAccounts);
156
- await refreshProfile('AccountsContext.updateProfile');
157
- return result as User;
150
+ await updateMutation(data, apiAccounts);
151
+ const user = await refreshProfile({ callerId: 'updateProfile', force: true });
152
+ return user as User;
158
153
  };
159
154
 
160
- // Partial update profile
155
+ // Partial update profile - then reload from API
161
156
  const partialUpdateProfile = async (data: PatchedUserProfileUpdateRequest): Promise<User> => {
162
- const result = await partialUpdateMutation(data, apiAccounts);
163
- await refreshProfile('AccountsContext.partialUpdateProfile');
164
- return result as User;
157
+ await partialUpdateMutation(data, apiAccounts);
158
+ const user = await refreshProfile({ callerId: 'partialUpdateProfile', force: true });
159
+ return user as User;
165
160
  };
166
161
 
167
- // Upload avatar
162
+ // Upload avatar - then reload from API
168
163
  const uploadAvatar = async (avatar: File | Blob): Promise<User> => {
169
- const result = await avatarMutation({ avatar }, apiAccounts);
170
- await refreshProfile('AccountsContext.uploadAvatar');
171
- return result as User;
164
+ await avatarMutation({ avatar }, apiAccounts);
165
+ const user = await refreshProfile({ callerId: 'uploadAvatar', force: true });
166
+ return user as User;
172
167
  };
173
168
 
174
169
  // Request OTP
@@ -192,7 +187,7 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
192
187
  if (result.access && result.refresh) {
193
188
  apiAccounts.setToken(result.access, result.refresh);
194
189
  // Refresh profile to load user data with new token
195
- await refreshProfile('AccountsContext.verifyOTP');
190
+ await refreshProfile({ callerId: 'verifyOTP', force: true });
196
191
  }
197
192
 
198
193
  return result as OTPVerifyResponse;
@@ -163,8 +163,8 @@ const AuthProviderInternal: React.FC<AuthProviderProps> = ({ children, config })
163
163
  return;
164
164
  }
165
165
 
166
- // Refresh profile from AccountsContext (now with memoization)
167
- const refreshedProfile = await accounts.refreshProfile(finalCallerId);
166
+ // Refresh profile from AccountsContext
167
+ const refreshedProfile = await accounts.refreshProfile({ callerId: finalCallerId });
168
168
 
169
169
  if (refreshedProfile) {
170
170
  authLogger.info('Profile loaded successfully:', refreshedProfile.id);
@@ -12,7 +12,7 @@ import { z } from 'zod'
12
12
  export const CentrifugoTokenSchema = z.object({
13
13
  token: z.string(),
14
14
  centrifugo_url: z.union([z.url(), z.literal('')]),
15
- expires_at: z.iso.datetime(),
15
+ expires_at: z.string().datetime({ offset: true }),
16
16
  channels: z.array(z.string()),
17
17
  })
18
18
 
@@ -17,8 +17,8 @@ export const OAuthConnectionSchema = z.object({
17
17
  provider_username: z.string(),
18
18
  provider_email: z.email(),
19
19
  provider_avatar_url: z.union([z.url(), z.literal('')]),
20
- connected_at: z.iso.datetime(),
21
- last_login_at: z.iso.datetime(),
20
+ connected_at: z.string().datetime({ offset: true }),
21
+ last_login_at: z.string().datetime({ offset: true }),
22
22
  })
23
23
 
24
24
  /**
@@ -11,7 +11,7 @@ import * as Enums from '../../enums'
11
11
  * Request to disconnect OAuth provider.
12
12
  */
13
13
  export const OAuthDisconnectRequestRequestSchema = z.object({
14
- provider: z.nativeEnum(Enums.OAuthDisconnectRequestRequestProvider),
14
+ provider: z.nativeEnum(Enums.OAuthConnectionProvider),
15
15
  })
16
16
 
17
17
  /**
@@ -13,7 +13,7 @@ import * as Enums from '../../enums'
13
13
  export const OTPVerifyRequestSchema = z.object({
14
14
  identifier: z.string().min(1),
15
15
  otp: z.string().min(6).max(6),
16
- channel: z.nativeEnum(Enums.OTPVerifyRequestChannel).optional(),
16
+ channel: z.nativeEnum(Enums.OTPRequestRequestChannel).optional(),
17
17
  source_url: z.union([z.url(), z.literal('')]).optional(),
18
18
  })
19
19
 
@@ -24,8 +24,8 @@ export const UserSchema = z.object({
24
24
  avatar: z.union([z.url(), z.literal('')]).nullable(),
25
25
  is_staff: z.boolean(),
26
26
  is_superuser: z.boolean(),
27
- date_joined: z.iso.datetime(),
28
- last_login: z.iso.datetime().nullable(),
27
+ date_joined: z.string().datetime({ offset: true }),
28
+ last_login: z.string().datetime({ offset: true }).nullable(),
29
29
  unanswered_messages_count: z.int(),
30
30
  centrifugo: CentrifugoTokenSchema.nullable(),
31
31
  })
@@ -51,7 +51,7 @@ export interface OTPVerifyRequest {
51
51
 
52
52
  * `email` - Email
53
53
  * `phone` - Phone */
54
- channel?: Enums.OTPVerifyRequestChannel;
54
+ channel?: Enums.OTPRequestRequestChannel;
55
55
  /** Source URL for tracking login (e.g., https://my.djangocfg.com) */
56
56
  source_url?: string;
57
57
  }
@@ -18,7 +18,7 @@ export class Oauth {
18
18
  */
19
19
  async accountsOauthConnectionsList(): Promise<any> {
20
20
  const response = await this.client.request('GET', "/cfg/accounts/oauth/connections/");
21
- return response;
21
+ return (response as any).results || response;
22
22
  }
23
23
 
24
24
  /**
@@ -10,7 +10,7 @@ export interface OAuthDisconnectRequestRequest {
10
10
  /** OAuth provider to disconnect
11
11
 
12
12
  * `github` - GitHub */
13
- provider: Enums.OAuthDisconnectRequestRequestProvider;
13
+ provider: Enums.OAuthConnectionProvider;
14
14
  }
15
15
 
16
16
  /**
@@ -1,17 +1,9 @@
1
1
  // Auto-generated by DjangoCFG - see CLAUDE.md
2
- /**
3
- * OAuth provider name (github, google, etc.)
4
- * * `github` - GitHub
5
- */
6
- export enum OAuthConnectionProvider {
7
- GITHUB = "github",
8
- }
9
-
10
2
  /**
11
3
  * OAuth provider to disconnect
12
4
  * * `github` - GitHub
13
5
  */
14
- export enum OAuthDisconnectRequestRequestProvider {
6
+ export enum OAuthConnectionProvider {
15
7
  GITHUB = "github",
16
8
  }
17
9
 
@@ -25,13 +17,3 @@ export enum OTPRequestRequestChannel {
25
17
  PHONE = "phone",
26
18
  }
27
19
 
28
- /**
29
- * Delivery channel: 'email' or 'phone'. Auto-detected if not provided.
30
- * * `email` - Email
31
- * * `phone` - Phone
32
- */
33
- export enum OTPVerifyRequestChannel {
34
- EMAIL = "email",
35
- PHONE = "phone",
36
- }
37
-
@@ -215,10 +215,10 @@ export async function getCentrifugoMonitorOverviewRetrieve( params?: { hours?:
215
215
  * @method GET
216
216
  * @path /cfg/centrifugo/monitor/publishes/
217
217
  */
218
- export async function getCentrifugoMonitorPublishesList( params?: { channel?: string; page?: number; page_size?: number; status?: string }, client?: any
218
+ export async function getCentrifugoMonitorPublishesList( params?: { channel?: string; ordering?: string; page?: number; page_size?: number; search?: string; status?: string }, client?: any
219
219
  ): Promise<PaginatedPublishList> {
220
220
  const api = client || getAPIInstance()
221
- const response = await api.centrifugo_monitoring.centrifugoMonitorPublishesList(params?.channel, params?.page, params?.page_size, params?.status)
221
+ const response = await api.centrifugo_monitoring.centrifugoMonitorPublishesList(params?.channel, params?.ordering, params?.page, params?.page_size, params?.search, params?.status)
222
222
  try {
223
223
  return PaginatedPublishListSchema.parse(response)
224
224
  } catch (error) {
@@ -74,7 +74,7 @@ export function useCentrifugoMonitorOverviewRetrieve(params?: { hours?: number }
74
74
  * @method GET
75
75
  * @path /cfg/centrifugo/monitor/publishes/
76
76
  */
77
- export function useCentrifugoMonitorPublishesList(params?: { channel?: string; page?: number; page_size?: number; status?: string }, client?: API): ReturnType<typeof useSWR<PaginatedPublishList>> {
77
+ export function useCentrifugoMonitorPublishesList(params?: { channel?: string; ordering?: string; page?: number; page_size?: number; search?: string; status?: string }, client?: API): ReturnType<typeof useSWR<PaginatedPublishList>> {
78
78
  return useSWR<PaginatedPublishList>(
79
79
  params ? ['cfg-centrifugo-monitor-publishes', params] : 'cfg-centrifugo-monitor-publishes',
80
80
  () => Fetchers.getCentrifugoMonitorPublishesList(params, client)
@@ -17,8 +17,8 @@ export const PublishSchema = z.object({
17
17
  acks_received: z.int(),
18
18
  acks_expected: z.int().nullable(),
19
19
  duration_ms: z.number().nullable(),
20
- created_at: z.iso.datetime(),
21
- completed_at: z.iso.datetime().nullable(),
20
+ created_at: z.string().datetime({ offset: true }),
21
+ completed_at: z.string().datetime({ offset: true }).nullable(),
22
22
  error_code: z.string().nullable(),
23
23
  error_message: z.string().nullable(),
24
24
  })
@@ -63,8 +63,8 @@ export class CentrifugoMonitoring {
63
63
  return response;
64
64
  }
65
65
 
66
- async centrifugoMonitorPublishesList(channel?: string, page?: number, page_size?: number, status?: string): Promise<Models.PaginatedPublishList>;
67
- async centrifugoMonitorPublishesList(params?: { channel?: string; page?: number; page_size?: number; status?: string }): Promise<Models.PaginatedPublishList>;
66
+ async centrifugoMonitorPublishesList(channel?: string, ordering?: string, page?: number, page_size?: number, search?: string, status?: string): Promise<Models.PaginatedPublishList>;
67
+ async centrifugoMonitorPublishesList(params?: { channel?: string; ordering?: string; page?: number; page_size?: number; search?: string; status?: string }): Promise<Models.PaginatedPublishList>;
68
68
 
69
69
  /**
70
70
  * Get recent publishes
@@ -79,7 +79,7 @@ export class CentrifugoMonitoring {
79
79
  if (isParamsObject) {
80
80
  params = args[0];
81
81
  } else {
82
- params = { channel: args[0], page: args[1], page_size: args[2], status: args[3] };
82
+ params = { channel: args[0], ordering: args[1], page: args[2], page_size: args[3], search: args[4], status: args[5] };
83
83
  }
84
84
  const response = await this.client.request('GET', "/cfg/centrifugo/monitor/publishes/", { params });
85
85
  return response;
@@ -228,6 +228,15 @@
228
228
  },
229
229
  "description": "Filter by channel name"
230
230
  },
231
+ {
232
+ "name": "ordering",
233
+ "required": false,
234
+ "in": "query",
235
+ "description": "Which field to use when ordering the results.",
236
+ "schema": {
237
+ "type": "string"
238
+ }
239
+ },
231
240
  {
232
241
  "in": "query",
233
242
  "name": "page",
@@ -244,6 +253,15 @@
244
253
  },
245
254
  "description": "Items per page (default: 10, max: 100)"
246
255
  },
256
+ {
257
+ "name": "search",
258
+ "required": false,
259
+ "in": "query",
260
+ "description": "A search term.",
261
+ "schema": {
262
+ "type": "string"
263
+ }
264
+ },
247
265
  {
248
266
  "in": "query",
249
267
  "name": "status",
@@ -41,10 +41,10 @@ import { getAPIInstance } from '../../api-instance'
41
41
  * @method GET
42
42
  * @path /cfg/totp/devices/
43
43
  */
44
- export async function getTotpDevicesList( params?: { page?: number; page_size?: number }, client?: any
44
+ export async function getTotpDevicesList( params?: { ordering?: string; page?: number; page_size?: number; search?: string }, client?: any
45
45
  ): Promise<PaginatedDeviceListResponseList> {
46
46
  const api = client || getAPIInstance()
47
- const response = await api.totp_management.totpDevicesList(params?.page, params?.page_size)
47
+ const response = await api.totp_management.totpDevicesList(params?.ordering, params?.page, params?.page_size, params?.search)
48
48
  try {
49
49
  return PaginatedDeviceListResponseListSchema.parse(response)
50
50
  } catch (error) {
@@ -30,7 +30,7 @@ import type { PaginatedDeviceListResponseList } from '../schemas/PaginatedDevice
30
30
  * @method GET
31
31
  * @path /cfg/totp/devices/
32
32
  */
33
- export function useTotpDevicesList(params?: { page?: number; page_size?: number }, client?: API): ReturnType<typeof useSWR<PaginatedDeviceListResponseList>> {
33
+ export function useTotpDevicesList(params?: { ordering?: string; page?: number; page_size?: number; search?: string }, client?: API): ReturnType<typeof useSWR<PaginatedDeviceListResponseList>> {
34
34
  return useSWR<PaginatedDeviceListResponseList>(
35
35
  params ? ['cfg-totp-devices', params] : 'cfg-totp-devices',
36
36
  () => Fetchers.getTotpDevicesList(params, client)
@@ -15,9 +15,9 @@ export const DeviceListSchema = z.object({
15
15
  name: z.string(),
16
16
  is_primary: z.boolean(),
17
17
  status: z.nativeEnum(Enums.DeviceListStatus),
18
- created_at: z.iso.datetime(),
19
- confirmed_at: z.iso.datetime().nullable(),
20
- last_used_at: z.iso.datetime().nullable(),
18
+ created_at: z.string().datetime({ offset: true }),
19
+ confirmed_at: z.string().datetime({ offset: true }).nullable(),
20
+ last_used_at: z.string().datetime({ offset: true }).nullable(),
21
21
  })
22
22
 
23
23
  /**
@@ -23,8 +23,8 @@ export const TotpVerifyUserSchema = z.object({
23
23
  avatar: z.union([z.url(), z.literal('')]).nullable(),
24
24
  is_staff: z.boolean(),
25
25
  is_superuser: z.boolean(),
26
- date_joined: z.iso.datetime(),
27
- last_login: z.iso.datetime().nullable(),
26
+ date_joined: z.string().datetime({ offset: true }),
27
+ last_login: z.string().datetime({ offset: true }).nullable(),
28
28
  unanswered_messages_count: z.int(),
29
29
  })
30
30
 
@@ -103,6 +103,15 @@
103
103
  "operationId": "cfg_totp_devices_list",
104
104
  "description": "List all TOTP devices for user.",
105
105
  "parameters": [
106
+ {
107
+ "name": "ordering",
108
+ "required": false,
109
+ "in": "query",
110
+ "description": "Which field to use when ordering the results.",
111
+ "schema": {
112
+ "type": "string"
113
+ }
114
+ },
106
115
  {
107
116
  "name": "page",
108
117
  "required": false,
@@ -120,6 +129,15 @@
120
129
  "schema": {
121
130
  "type": "integer"
122
131
  }
132
+ },
133
+ {
134
+ "name": "search",
135
+ "required": false,
136
+ "in": "query",
137
+ "description": "A search term.",
138
+ "schema": {
139
+ "type": "string"
140
+ }
123
141
  }
124
142
  ],
125
143
  "tags": [
@@ -11,8 +11,8 @@ export class TotpManagement {
11
11
  this.client = client;
12
12
  }
13
13
 
14
- async totpDevicesList(page?: number, page_size?: number): Promise<Models.PaginatedDeviceListResponseList>;
15
- async totpDevicesList(params?: { page?: number; page_size?: number }): Promise<Models.PaginatedDeviceListResponseList>;
14
+ async totpDevicesList(ordering?: string, page?: number, page_size?: number, search?: string): Promise<Models.PaginatedDeviceListResponseList>;
15
+ async totpDevicesList(params?: { ordering?: string; page?: number; page_size?: number; search?: string }): Promise<Models.PaginatedDeviceListResponseList>;
16
16
 
17
17
  /**
18
18
  * List all TOTP devices for user.
@@ -24,7 +24,7 @@ export class TotpManagement {
24
24
  if (isParamsObject) {
25
25
  params = args[0];
26
26
  } else {
27
- params = { page: args[0], page_size: args[1] };
27
+ params = { ordering: args[0], page: args[1], page_size: args[2], search: args[3] };
28
28
  }
29
29
  const response = await this.client.request('GET', "/cfg/totp/devices/", { params });
30
30
  return response;