hazo_auth 1.6.0 → 1.6.2

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 (74) hide show
  1. package/README.md +191 -19
  2. package/SETUP_CHECKLIST.md +190 -65
  3. package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts +9 -0
  4. package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts.map +1 -0
  5. package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.js +82 -0
  6. package/dist/app/api/hazo_auth/library_photos/route.d.ts +9 -0
  7. package/dist/app/api/hazo_auth/library_photos/route.d.ts.map +1 -1
  8. package/dist/app/api/hazo_auth/library_photos/route.js +31 -6
  9. package/dist/cli/generate.d.ts +6 -1
  10. package/dist/cli/generate.d.ts.map +1 -1
  11. package/dist/cli/generate.js +101 -34
  12. package/dist/cli/index.js +64 -11
  13. package/dist/cli/init.d.ts +2 -0
  14. package/dist/cli/init.d.ts.map +1 -0
  15. package/dist/cli/init.js +206 -0
  16. package/dist/client.d.ts +8 -0
  17. package/dist/client.d.ts.map +1 -0
  18. package/dist/client.js +25 -0
  19. package/dist/components/layouts/email_verification/index.d.ts +2 -1
  20. package/dist/components/layouts/email_verification/index.d.ts.map +1 -1
  21. package/dist/components/layouts/email_verification/index.js +3 -2
  22. package/dist/components/layouts/forgot_password/index.d.ts +3 -1
  23. package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
  24. package/dist/components/layouts/forgot_password/index.js +3 -2
  25. package/dist/components/layouts/my_settings/components/editable_field.js +1 -1
  26. package/dist/components/layouts/my_settings/components/password_change_dialog.js +1 -1
  27. package/dist/components/layouts/my_settings/components/profile_picture_display.js +1 -1
  28. package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.js +1 -1
  29. package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +4 -4
  30. package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.js +4 -4
  31. package/dist/components/layouts/my_settings/index.js +1 -1
  32. package/dist/components/layouts/shared/components/profile_pic_menu.js +2 -2
  33. package/dist/lib/auth_utility_config.server.js +2 -2
  34. package/dist/lib/services/profile_picture_service.d.ts +34 -2
  35. package/dist/lib/services/profile_picture_service.d.ts.map +1 -1
  36. package/dist/lib/services/profile_picture_service.js +157 -15
  37. package/dist/lib/services/user_profiles_cache.d.ts +76 -0
  38. package/dist/lib/services/user_profiles_cache.d.ts.map +1 -0
  39. package/dist/lib/services/user_profiles_cache.js +141 -0
  40. package/dist/lib/services/user_profiles_service.d.ts +17 -0
  41. package/dist/lib/services/user_profiles_service.d.ts.map +1 -1
  42. package/dist/lib/services/user_profiles_service.js +136 -44
  43. package/dist/lib/user_profiles_config.server.d.ts +15 -0
  44. package/dist/lib/user_profiles_config.server.d.ts.map +1 -0
  45. package/dist/lib/user_profiles_config.server.js +23 -0
  46. package/dist/page_components/forgot_password.d.ts +19 -0
  47. package/dist/page_components/forgot_password.d.ts.map +1 -0
  48. package/dist/page_components/forgot_password.js +36 -0
  49. package/dist/page_components/index.d.ts +7 -0
  50. package/dist/page_components/index.d.ts.map +1 -0
  51. package/dist/page_components/index.js +9 -0
  52. package/dist/page_components/login.d.ts +26 -0
  53. package/dist/page_components/login.d.ts.map +1 -0
  54. package/dist/page_components/login.js +40 -0
  55. package/dist/page_components/my_settings.d.ts +64 -0
  56. package/dist/page_components/my_settings.d.ts.map +1 -0
  57. package/dist/page_components/my_settings.js +67 -0
  58. package/dist/page_components/register.d.ts +25 -0
  59. package/dist/page_components/register.d.ts.map +1 -0
  60. package/dist/page_components/register.js +43 -0
  61. package/dist/page_components/reset_password.d.ts +25 -0
  62. package/dist/page_components/reset_password.d.ts.map +1 -0
  63. package/dist/page_components/reset_password.js +43 -0
  64. package/dist/page_components/verify_email.d.ts +21 -0
  65. package/dist/page_components/verify_email.d.ts.map +1 -0
  66. package/dist/page_components/verify_email.js +36 -0
  67. package/dist/server/routes/index.d.ts +1 -0
  68. package/dist/server/routes/index.d.ts.map +1 -1
  69. package/dist/server/routes/index.js +1 -0
  70. package/dist/server/routes/library_photo.d.ts +2 -0
  71. package/dist/server/routes/library_photo.d.ts.map +1 -0
  72. package/dist/server/routes/library_photo.js +3 -0
  73. package/hazo_auth_config.example.ini +25 -5
  74. package/package.json +33 -1
@@ -7,7 +7,52 @@ import { create_app_logger } from "../app_logger";
7
7
  import path from "path";
8
8
  import fs from "fs";
9
9
  import { map_ui_source_to_db } from "./profile_picture_source_mapper";
10
+ // section: cache
11
+ // Cache the resolved library path to avoid repeated filesystem checks
12
+ let cached_library_path = null;
13
+ let cached_library_source = null;
10
14
  // section: helpers
15
+ /**
16
+ * Resolves the library path, checking project's public folder first, then node_modules
17
+ * @returns Object with path and source, or null if not found
18
+ */
19
+ function resolve_library_path() {
20
+ // Return cached value if available
21
+ if (cached_library_path && cached_library_source) {
22
+ if (fs.existsSync(cached_library_path)) {
23
+ return { path: cached_library_path, source: cached_library_source };
24
+ }
25
+ // Cache is stale, clear it
26
+ cached_library_path = null;
27
+ cached_library_source = null;
28
+ }
29
+ const config = get_profile_picture_config();
30
+ const library_subpath = config.library_photo_path.replace(/^\//, "");
31
+ // Try 1: Project's public folder
32
+ const project_library_path = path.resolve(process.cwd(), "public", library_subpath);
33
+ if (fs.existsSync(project_library_path)) {
34
+ // Check if it has any content (not just empty directory)
35
+ try {
36
+ const entries = fs.readdirSync(project_library_path);
37
+ if (entries.length > 0) {
38
+ cached_library_path = project_library_path;
39
+ cached_library_source = "project";
40
+ return { path: project_library_path, source: "project" };
41
+ }
42
+ }
43
+ catch (_a) {
44
+ // Continue to fallback
45
+ }
46
+ }
47
+ // Try 2: node_modules/hazo_auth/public folder
48
+ const node_modules_library_path = path.resolve(process.cwd(), "node_modules", "hazo_auth", "public", library_subpath);
49
+ if (fs.existsSync(node_modules_library_path)) {
50
+ cached_library_path = node_modules_library_path;
51
+ cached_library_source = "node_modules";
52
+ return { path: node_modules_library_path, source: "node_modules" };
53
+ }
54
+ return null;
55
+ }
11
56
  /**
12
57
  * Generates Gravatar URL from email address
13
58
  * @param email - User's email address
@@ -27,13 +72,12 @@ export function get_gravatar_url(email, size) {
27
72
  * @returns Array of category names
28
73
  */
29
74
  export function get_library_categories() {
30
- const config = get_profile_picture_config();
31
- const library_path = path.resolve(process.cwd(), "public", config.library_photo_path.replace(/^\//, ""));
32
- if (!fs.existsSync(library_path)) {
75
+ const resolved = resolve_library_path();
76
+ if (!resolved) {
33
77
  return [];
34
78
  }
35
79
  try {
36
- const entries = fs.readdirSync(library_path, { withFileTypes: true });
80
+ const entries = fs.readdirSync(resolved.path, { withFileTypes: true });
37
81
  return entries
38
82
  .filter((entry) => entry.isDirectory())
39
83
  .map((entry) => entry.name)
@@ -45,37 +89,84 @@ export function get_library_categories() {
45
89
  logger.warn("profile_picture_service_read_categories_failed", {
46
90
  filename: "profile_picture_service.ts",
47
91
  line_number: 0,
48
- library_path,
92
+ library_path: resolved.path,
93
+ source: resolved.source,
49
94
  error: error_message,
50
95
  });
51
96
  return [];
52
97
  }
53
98
  }
54
99
  /**
55
- * Gets photos in a specific library category
100
+ * Gets photos in a specific library category with pagination support
56
101
  * @param category - Category name
57
- * @returns Array of photo URLs (relative to public directory)
102
+ * @param page - Page number (1-indexed, default 1)
103
+ * @param page_size - Number of photos per page (default 20, max 100)
104
+ * @returns Object with photos array and pagination info
58
105
  */
59
- export function get_library_photos(category) {
106
+ export function get_library_photos_paginated(category, page = 1, page_size = 20) {
107
+ const resolved = resolve_library_path();
60
108
  const config = get_profile_picture_config();
61
- const category_path = path.resolve(process.cwd(), "public", config.library_photo_path.replace(/^\//, ""), category);
109
+ // Ensure page_size is within bounds
110
+ const effective_page_size = Math.min(Math.max(1, page_size), 100);
111
+ const effective_page = Math.max(1, page);
112
+ if (!resolved) {
113
+ return {
114
+ photos: [],
115
+ total: 0,
116
+ page: effective_page,
117
+ page_size: effective_page_size,
118
+ has_more: false,
119
+ source: "project",
120
+ };
121
+ }
122
+ const category_path = path.join(resolved.path, category);
62
123
  if (!fs.existsSync(category_path)) {
63
- return [];
124
+ return {
125
+ photos: [],
126
+ total: 0,
127
+ page: effective_page,
128
+ page_size: effective_page_size,
129
+ has_more: false,
130
+ source: resolved.source,
131
+ };
64
132
  }
65
133
  try {
66
134
  const fileTypes = get_file_types_config();
67
- const allowedExtensions = fileTypes.allowed_image_extensions.map(ext => `.${ext.toLowerCase()}`);
135
+ const allowedExtensions = fileTypes.allowed_image_extensions.map(ext => ext.startsWith(".") ? ext.toLowerCase() : `.${ext.toLowerCase()}`);
68
136
  const entries = fs.readdirSync(category_path, { withFileTypes: true });
69
- const photos = entries
137
+ const all_photos = entries
70
138
  .filter((entry) => {
71
139
  if (!entry.isFile())
72
140
  return false;
73
141
  const ext = path.extname(entry.name).toLowerCase();
74
142
  return allowedExtensions.includes(ext);
75
143
  })
76
- .map((entry) => `${config.library_photo_path}/${category}/${entry.name}`)
144
+ .map((entry) => entry.name)
77
145
  .sort();
78
- return photos;
146
+ const total = all_photos.length;
147
+ const start_index = (effective_page - 1) * effective_page_size;
148
+ const end_index = start_index + effective_page_size;
149
+ const page_photos = all_photos.slice(start_index, end_index);
150
+ // Generate URLs based on source
151
+ // For node_modules source, we need to serve via API route
152
+ const photo_urls = page_photos.map((filename) => {
153
+ if (resolved.source === "node_modules") {
154
+ // Serve via API route that reads from node_modules
155
+ return `/api/hazo_auth/library_photo/${category}/${filename}`;
156
+ }
157
+ else {
158
+ // Serve directly from public folder
159
+ return `${config.library_photo_path}/${category}/${filename}`;
160
+ }
161
+ });
162
+ return {
163
+ photos: photo_urls,
164
+ total,
165
+ page: effective_page,
166
+ page_size: effective_page_size,
167
+ has_more: end_index < total,
168
+ source: resolved.source,
169
+ };
79
170
  }
80
171
  catch (error) {
81
172
  const logger = create_app_logger();
@@ -85,10 +176,61 @@ export function get_library_photos(category) {
85
176
  line_number: 0,
86
177
  category,
87
178
  category_path,
179
+ source: resolved.source,
88
180
  error: error_message,
89
181
  });
90
- return [];
182
+ return {
183
+ photos: [],
184
+ total: 0,
185
+ page: effective_page,
186
+ page_size: effective_page_size,
187
+ has_more: false,
188
+ source: resolved.source,
189
+ };
190
+ }
191
+ }
192
+ /**
193
+ * Gets photos in a specific library category (legacy non-paginated version)
194
+ * @param category - Category name
195
+ * @returns Array of photo URLs (relative to public directory or API route)
196
+ */
197
+ export function get_library_photos(category) {
198
+ // Use paginated version with large page size for backwards compatibility
199
+ const result = get_library_photos_paginated(category, 1, 1000);
200
+ return result.photos;
201
+ }
202
+ /**
203
+ * Gets the physical file path for a library photo (used for serving from node_modules)
204
+ * @param category - Category name
205
+ * @param filename - Photo filename
206
+ * @returns Full file path or null if not found
207
+ */
208
+ export function get_library_photo_path(category, filename) {
209
+ const resolved = resolve_library_path();
210
+ if (!resolved) {
211
+ return null;
212
+ }
213
+ const photo_path = path.join(resolved.path, category, filename);
214
+ if (fs.existsSync(photo_path)) {
215
+ return photo_path;
91
216
  }
217
+ return null;
218
+ }
219
+ /**
220
+ * Gets the source of library photos (for diagnostic purposes)
221
+ * @returns Source type or null if no library found
222
+ */
223
+ export function get_library_source() {
224
+ var _a;
225
+ const resolved = resolve_library_path();
226
+ return (_a = resolved === null || resolved === void 0 ? void 0 : resolved.source) !== null && _a !== void 0 ? _a : null;
227
+ }
228
+ /**
229
+ * Clears the library path cache (useful for testing or after copying files)
230
+ */
231
+ export function clear_library_cache() {
232
+ cached_library_path = null;
233
+ cached_library_source = null;
92
234
  }
93
235
  /**
94
236
  * Gets default profile picture based on configuration priority
@@ -0,0 +1,76 @@
1
+ import type { UserProfileInfo } from "./user_profiles_service";
2
+ /**
3
+ * LRU cache implementation with TTL and size limits for user profiles
4
+ * Uses Map to maintain insertion order for LRU eviction
5
+ */
6
+ declare class UserProfilesCache {
7
+ private cache;
8
+ private max_size;
9
+ private ttl_ms;
10
+ constructor(max_size: number, ttl_minutes: number);
11
+ /**
12
+ * Gets a cached profile for a user
13
+ * Returns undefined if not found or expired
14
+ * @param user_id - User ID to look up
15
+ * @returns Profile or undefined
16
+ */
17
+ get(user_id: string): UserProfileInfo | undefined;
18
+ /**
19
+ * Gets multiple profiles from cache
20
+ * Returns object with found profiles and missing IDs
21
+ * @param user_ids - Array of user IDs to look up
22
+ * @returns Object with cached profiles and IDs not in cache
23
+ */
24
+ get_many(user_ids: string[]): {
25
+ cached: UserProfileInfo[];
26
+ missing_ids: string[];
27
+ };
28
+ /**
29
+ * Sets a cache entry for a user profile
30
+ * Evicts least recently used entries if cache is full
31
+ * @param user_id - User ID
32
+ * @param profile - User profile data
33
+ */
34
+ set(user_id: string, profile: UserProfileInfo): void;
35
+ /**
36
+ * Sets multiple cache entries at once
37
+ * @param profiles - Array of user profiles to cache
38
+ */
39
+ set_many(profiles: UserProfileInfo[]): void;
40
+ /**
41
+ * Invalidates cache for a specific user
42
+ * @param user_id - User ID to invalidate
43
+ */
44
+ invalidate_user(user_id: string): void;
45
+ /**
46
+ * Invalidates cache for multiple users
47
+ * @param user_ids - Array of user IDs to invalidate
48
+ */
49
+ invalidate_users(user_ids: string[]): void;
50
+ /**
51
+ * Invalidates all cache entries
52
+ */
53
+ invalidate_all(): void;
54
+ /**
55
+ * Gets cache statistics
56
+ * @returns Object with cache size and max size
57
+ */
58
+ get_stats(): {
59
+ size: number;
60
+ max_size: number;
61
+ ttl_minutes: number;
62
+ };
63
+ }
64
+ /**
65
+ * Gets or creates the global user profiles cache instance
66
+ * @param max_size - Maximum cache size (default: 5000)
67
+ * @param ttl_minutes - TTL in minutes (default: 5)
68
+ * @returns User profiles cache instance
69
+ */
70
+ export declare function get_user_profiles_cache(max_size?: number, ttl_minutes?: number): UserProfilesCache;
71
+ /**
72
+ * Resets the global cache instance (useful for testing)
73
+ */
74
+ export declare function reset_user_profiles_cache(): void;
75
+ export {};
76
+ //# sourceMappingURL=user_profiles_cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user_profiles_cache.d.ts","sourceRoot":"","sources":["../../../src/lib/services/user_profiles_cache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAc/D;;;GAGG;AACH,cAAM,iBAAiB;IACrB,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAMjD;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAuBjD;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG;QAC5B,MAAM,EAAE,eAAe,EAAE,CAAC;QAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB;IAgBD;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAmBpD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,IAAI;IAM3C;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAItC;;;OAGG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAM1C;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;;OAGG;IACH,SAAS,IAAI;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB;CAOF;AAMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,GAAE,MAAa,EACvB,WAAW,GAAE,MAAU,GACtB,iBAAiB,CAKnB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
@@ -0,0 +1,141 @@
1
+ // section: cache_class
2
+ /**
3
+ * LRU cache implementation with TTL and size limits for user profiles
4
+ * Uses Map to maintain insertion order for LRU eviction
5
+ */
6
+ class UserProfilesCache {
7
+ constructor(max_size, ttl_minutes) {
8
+ this.cache = new Map();
9
+ this.max_size = max_size;
10
+ this.ttl_ms = ttl_minutes * 60 * 1000;
11
+ }
12
+ /**
13
+ * Gets a cached profile for a user
14
+ * Returns undefined if not found or expired
15
+ * @param user_id - User ID to look up
16
+ * @returns Profile or undefined
17
+ */
18
+ get(user_id) {
19
+ const entry = this.cache.get(user_id);
20
+ if (!entry) {
21
+ return undefined;
22
+ }
23
+ const now = Date.now();
24
+ const age = now - entry.timestamp;
25
+ // Check if entry is expired
26
+ if (age > this.ttl_ms) {
27
+ this.cache.delete(user_id);
28
+ return undefined;
29
+ }
30
+ // Move to end (most recently used)
31
+ this.cache.delete(user_id);
32
+ this.cache.set(user_id, entry);
33
+ return entry.profile;
34
+ }
35
+ /**
36
+ * Gets multiple profiles from cache
37
+ * Returns object with found profiles and missing IDs
38
+ * @param user_ids - Array of user IDs to look up
39
+ * @returns Object with cached profiles and IDs not in cache
40
+ */
41
+ get_many(user_ids) {
42
+ const cached = [];
43
+ const missing_ids = [];
44
+ for (const user_id of user_ids) {
45
+ const profile = this.get(user_id);
46
+ if (profile) {
47
+ cached.push(profile);
48
+ }
49
+ else {
50
+ missing_ids.push(user_id);
51
+ }
52
+ }
53
+ return { cached, missing_ids };
54
+ }
55
+ /**
56
+ * Sets a cache entry for a user profile
57
+ * Evicts least recently used entries if cache is full
58
+ * @param user_id - User ID
59
+ * @param profile - User profile data
60
+ */
61
+ set(user_id, profile) {
62
+ // Evict LRU entries if cache is full
63
+ while (this.cache.size >= this.max_size) {
64
+ const first_key = this.cache.keys().next().value;
65
+ if (first_key) {
66
+ this.cache.delete(first_key);
67
+ }
68
+ else {
69
+ break;
70
+ }
71
+ }
72
+ const entry = {
73
+ profile,
74
+ timestamp: Date.now(),
75
+ };
76
+ this.cache.set(user_id, entry);
77
+ }
78
+ /**
79
+ * Sets multiple cache entries at once
80
+ * @param profiles - Array of user profiles to cache
81
+ */
82
+ set_many(profiles) {
83
+ for (const profile of profiles) {
84
+ this.set(profile.user_id, profile);
85
+ }
86
+ }
87
+ /**
88
+ * Invalidates cache for a specific user
89
+ * @param user_id - User ID to invalidate
90
+ */
91
+ invalidate_user(user_id) {
92
+ this.cache.delete(user_id);
93
+ }
94
+ /**
95
+ * Invalidates cache for multiple users
96
+ * @param user_ids - Array of user IDs to invalidate
97
+ */
98
+ invalidate_users(user_ids) {
99
+ for (const user_id of user_ids) {
100
+ this.cache.delete(user_id);
101
+ }
102
+ }
103
+ /**
104
+ * Invalidates all cache entries
105
+ */
106
+ invalidate_all() {
107
+ this.cache.clear();
108
+ }
109
+ /**
110
+ * Gets cache statistics
111
+ * @returns Object with cache size and max size
112
+ */
113
+ get_stats() {
114
+ return {
115
+ size: this.cache.size,
116
+ max_size: this.max_size,
117
+ ttl_minutes: this.ttl_ms / 60000,
118
+ };
119
+ }
120
+ }
121
+ // section: singleton
122
+ // Global cache instance (initialized with defaults, will be configured on first use)
123
+ let user_profiles_cache_instance = null;
124
+ /**
125
+ * Gets or creates the global user profiles cache instance
126
+ * @param max_size - Maximum cache size (default: 5000)
127
+ * @param ttl_minutes - TTL in minutes (default: 5)
128
+ * @returns User profiles cache instance
129
+ */
130
+ export function get_user_profiles_cache(max_size = 5000, ttl_minutes = 5) {
131
+ if (!user_profiles_cache_instance) {
132
+ user_profiles_cache_instance = new UserProfilesCache(max_size, ttl_minutes);
133
+ }
134
+ return user_profiles_cache_instance;
135
+ }
136
+ /**
137
+ * Resets the global cache instance (useful for testing)
138
+ */
139
+ export function reset_user_profiles_cache() {
140
+ user_profiles_cache_instance = null;
141
+ }
@@ -19,13 +19,30 @@ export type GetProfilesResult = {
19
19
  profiles: UserProfileInfo[];
20
20
  not_found_ids: string[];
21
21
  error?: string;
22
+ cache_stats?: {
23
+ hits: number;
24
+ misses: number;
25
+ cache_enabled: boolean;
26
+ };
22
27
  };
23
28
  /**
24
29
  * Retrieves basic profile information for multiple users in a single batch call
25
30
  * Useful for chat applications and similar use cases where basic user info is needed
31
+ * Uses LRU cache with configurable TTL for performance (default: 5 minutes)
26
32
  * @param adapter - The hazo_connect adapter instance
27
33
  * @param user_ids - Array of user IDs to retrieve profiles for
28
34
  * @returns GetProfilesResult with found profiles and list of not found IDs
29
35
  */
30
36
  export declare function hazo_get_user_profiles(adapter: HazoConnectAdapter, user_ids: string[]): Promise<GetProfilesResult>;
37
+ /**
38
+ * Invalidates cache for specific user IDs
39
+ * Call this after user profile updates to ensure fresh data on next fetch
40
+ * @param user_ids - Array of user IDs to invalidate from cache
41
+ */
42
+ export declare function invalidate_user_profiles_cache(user_ids: string[]): void;
43
+ /**
44
+ * Invalidates the entire user profiles cache
45
+ * Use sparingly - prefer invalidating specific users when possible
46
+ */
47
+ export declare function invalidate_all_user_profiles_cache(): void;
31
48
  //# sourceMappingURL=user_profiles_service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"user_profiles_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/user_profiles_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAOvD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,iBAAiB,CAAC,CAkG5B"}
1
+ {"version":3,"file":"user_profiles_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/user_profiles_service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AASvD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;CACH,CAAC;AAuDF;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,iBAAiB,CAAC,CA4H5B;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAWvE;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,IAAI,IAAI,CAWzD"}