@crypto512/jicon-mcp 2.3.25 → 2.3.26

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.
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Shared user display name resolver
3
+ *
4
+ * Resolves Jira userkeys/usernames to display names via Jira REST API.
5
+ * Session-scoped cache ensures each user is resolved at most once per session,
6
+ * shared across Tempo and Confluence tools.
7
+ */
8
+ import { debug } from "./logger.js";
9
+ export class UserResolver {
10
+ cache = new Map();
11
+ fullCache = new Map();
12
+ http;
13
+ constructor(http) {
14
+ this.http = http;
15
+ }
16
+ /**
17
+ * Resolve a single userkey/username to display name
18
+ * Tries username lookup first, falls back to key lookup (for JIRAUSER/hex format)
19
+ */
20
+ async resolveUserDisplayName(userKey) {
21
+ if (this.cache.has(userKey)) {
22
+ return this.cache.get(userKey);
23
+ }
24
+ const resolved = await this.resolveUser(userKey);
25
+ return resolved.displayName;
26
+ }
27
+ /**
28
+ * Resolve a single userkey/username to full user info (username + displayName)
29
+ */
30
+ async resolveUser(userKey) {
31
+ if (this.fullCache.has(userKey)) {
32
+ return this.fullCache.get(userKey);
33
+ }
34
+ let resolved = { username: userKey, displayName: userKey };
35
+ try {
36
+ const user = await this.http.get(`/rest/api/2/user?username=${encodeURIComponent(userKey)}`);
37
+ resolved = {
38
+ username: user.name || userKey,
39
+ displayName: user.displayName || user.name || userKey,
40
+ };
41
+ }
42
+ catch {
43
+ try {
44
+ const user = await this.http.get(`/rest/api/2/user?key=${encodeURIComponent(userKey)}`);
45
+ resolved = {
46
+ username: user.name || userKey,
47
+ displayName: user.displayName || user.name || userKey,
48
+ };
49
+ }
50
+ catch {
51
+ debug(`User lookup failed for key: ${userKey}, using as-is`);
52
+ }
53
+ }
54
+ this.cache.set(userKey, resolved.displayName);
55
+ this.fullCache.set(userKey, resolved);
56
+ return resolved;
57
+ }
58
+ /**
59
+ * Resolve multiple userkeys to display names in parallel
60
+ * Uses persistent cache to avoid repeated API calls
61
+ */
62
+ async resolveUserDisplayNames(userKeys) {
63
+ const uniqueKeys = [...new Set(userKeys.filter(Boolean))];
64
+ const result = new Map();
65
+ const uncachedKeys = uniqueKeys.filter(key => !this.cache.has(key));
66
+ // Resolve in parallel batches of 5 to avoid rate limiting
67
+ const batchSize = 5;
68
+ for (let i = 0; i < uncachedKeys.length; i += batchSize) {
69
+ const batch = uncachedKeys.slice(i, i + batchSize);
70
+ await Promise.all(batch.map(key => this.resolveUser(key)));
71
+ }
72
+ for (const key of uniqueKeys) {
73
+ result.set(key, this.cache.get(key) || key);
74
+ }
75
+ return result;
76
+ }
77
+ /**
78
+ * Resolve multiple userkeys to full user info (username + displayName)
79
+ * Used by Confluence to produce @username (Display Name) in plain text
80
+ */
81
+ async resolveUsers(userKeys) {
82
+ const uniqueKeys = [...new Set(userKeys.filter(Boolean))];
83
+ const result = new Map();
84
+ const uncachedKeys = uniqueKeys.filter(key => !this.fullCache.has(key));
85
+ const batchSize = 5;
86
+ for (let i = 0; i < uncachedKeys.length; i += batchSize) {
87
+ const batch = uncachedKeys.slice(i, i + batchSize);
88
+ await Promise.all(batch.map(key => this.resolveUser(key)));
89
+ }
90
+ for (const key of uniqueKeys) {
91
+ result.set(key, this.fullCache.get(key) || { username: key, displayName: key });
92
+ }
93
+ return result;
94
+ }
95
+ }
96
+ //# sourceMappingURL=user-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-resolver.js","sourceRoot":"","sources":["../../src/utils/user-resolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crypto512/jicon-mcp",
3
- "version": "2.3.25",
3
+ "version": "2.3.26",
4
4
  "description": "Model Context Protocol server for Jira, Confluence, and Tempo integration",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",