@djangocfg/api 2.1.26 → 2.1.28

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/api",
3
- "version": "2.1.26",
3
+ "version": "2.1.28",
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",
@@ -69,7 +69,7 @@
69
69
  "check": "tsc --noEmit"
70
70
  },
71
71
  "peerDependencies": {
72
- "@djangocfg/ui-nextjs": "^2.1.26",
72
+ "@djangocfg/ui-nextjs": "^2.1.28",
73
73
  "consola": "^3.4.2",
74
74
  "next": "^14 || ^15",
75
75
  "p-retry": "^7.0.0",
@@ -80,7 +80,7 @@
80
80
  "devDependencies": {
81
81
  "@types/node": "^24.7.2",
82
82
  "@types/react": "^19.0.0",
83
- "@djangocfg/typescript-config": "^2.1.26",
83
+ "@djangocfg/typescript-config": "^2.1.28",
84
84
  "next": "^15.0.0",
85
85
  "react": "^19.0.0",
86
86
  "tsup": "^8.5.0",
@@ -14,4 +14,5 @@ export {
14
14
  hasValidCache,
15
15
  getCacheMetadata,
16
16
  type ProfileCacheOptions
17
- } from './useProfileCache';
17
+ } from './useProfileCache';
18
+ export { useBase64, encodeBase64, decodeBase64 } from './useBase64';
@@ -0,0 +1,80 @@
1
+ "use client"
2
+
3
+ /**
4
+ * Base64 Encoding/Decoding Hook
5
+ *
6
+ * Provides base64 encoding/decoding with dev mode detection:
7
+ * - In production: encodes data to base64
8
+ * - In development: returns data as-is (no encoding)
9
+ */
10
+
11
+ const isDev = process.env.NODE_ENV === 'development';
12
+
13
+ /**
14
+ * Encode string to base64
15
+ * @param data - String data to encode
16
+ * @returns Base64 encoded string (or original in dev mode)
17
+ */
18
+ export function encodeBase64(data: string): string {
19
+ if (isDev) {
20
+ return data;
21
+ }
22
+
23
+ try {
24
+ // Browser-safe base64 encoding
25
+ if (typeof window !== 'undefined') {
26
+ return btoa(encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, (_, p1) => {
27
+ return String.fromCharCode(parseInt(p1, 16));
28
+ }));
29
+ }
30
+ // Node.js fallback
31
+ return Buffer.from(data, 'utf-8').toString('base64');
32
+ } catch (error) {
33
+ console.error('Base64 encoding error:', error);
34
+ return data; // Return original on error
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Decode base64 to string
40
+ * @param encoded - Base64 encoded string
41
+ * @returns Decoded string (or original in dev mode)
42
+ */
43
+ export function decodeBase64(encoded: string): string {
44
+ if (isDev) {
45
+ return encoded;
46
+ }
47
+
48
+ try {
49
+ // Browser-safe base64 decoding
50
+ if (typeof window !== 'undefined') {
51
+ const binary = atob(encoded);
52
+ const bytes = new Uint8Array(binary.length);
53
+ for (let i = 0; i < binary.length; i++) {
54
+ bytes[i] = binary.charCodeAt(i);
55
+ }
56
+ return decodeURIComponent(
57
+ Array.from(bytes)
58
+ .map(byte => '%' + ('00' + byte.toString(16)).slice(-2))
59
+ .join('')
60
+ );
61
+ }
62
+ // Node.js fallback
63
+ return Buffer.from(encoded, 'base64').toString('utf-8');
64
+ } catch (error) {
65
+ console.error('Base64 decoding error:', error);
66
+ return encoded; // Return original on error
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Hook for base64 encoding/decoding
72
+ * @returns Object with encode and decode functions
73
+ */
74
+ export function useBase64() {
75
+ return {
76
+ encode: encodeBase64,
77
+ decode: decodeBase64,
78
+ isDev,
79
+ };
80
+ }
@@ -11,6 +11,7 @@
11
11
 
12
12
  import type { User } from '../../';
13
13
  import { authLogger as profileLogger } from '../utils/logger';
14
+ import { encodeBase64, decodeBase64 } from './useBase64';
14
15
 
15
16
  // Cache configuration
16
17
  const CACHE_KEY = 'user_profile_cache';
@@ -43,7 +44,9 @@ export function getCachedProfile(): User | null {
43
44
  return null;
44
45
  }
45
46
 
46
- const cachedData: CachedProfile = JSON.parse(cached);
47
+ // Decode from base64
48
+ const decoded = decodeBase64(cached);
49
+ const cachedData: CachedProfile = JSON.parse(decoded);
47
50
 
48
51
  // Version check
49
52
  if (cachedData.version !== CACHE_VERSION) {
@@ -86,7 +89,9 @@ export function setCachedProfile(profile: User, options?: ProfileCacheOptions):
86
89
  ttl: options?.ttl || DEFAULT_TTL,
87
90
  };
88
91
 
89
- localStorage.setItem(CACHE_KEY, JSON.stringify(cachedData));
92
+ // Encode to base64
93
+ const encoded = encodeBase64(JSON.stringify(cachedData));
94
+ localStorage.setItem(CACHE_KEY, encoded);
90
95
  profileLogger.debug('Profile cached, TTL:', cachedData.ttl / 1000, 'seconds');
91
96
  } catch (error) {
92
97
  profileLogger.error('Error writing cache:', error);
@@ -128,7 +133,9 @@ export function getCacheMetadata(): {
128
133
  const cached = localStorage.getItem(CACHE_KEY);
129
134
  if (!cached) return { exists: false };
130
135
 
131
- const cachedData: CachedProfile = JSON.parse(cached);
136
+ // Decode from base64
137
+ const decoded = decodeBase64(cached);
138
+ const cachedData: CachedProfile = JSON.parse(decoded);
132
139
  const now = Date.now();
133
140
  const age = now - cachedData.timestamp;
134
141
  const expiresIn = cachedData.ttl - age;