-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathsession-routing.ts
More file actions
119 lines (104 loc) · 3.03 KB
/
session-routing.ts
File metadata and controls
119 lines (104 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { buildSessionKey, parseSessionKey } from './session-key.js';
export type SessionDmScope = 'per-channel-peer' | 'per-linked-identity';
export interface SessionRoutingConfig {
dmScope: SessionDmScope;
identityLinks: Record<string, string[]>;
}
export interface ResolvedSessionRoutingScope {
mainSessionKey: string;
linkedIdentity?: string;
}
function normalizeRoutingToken(value: string): string {
return String(value || '')
.trim()
.toLowerCase();
}
export function normalizeSessionDmScope(
value: unknown,
fallback: SessionDmScope,
): SessionDmScope {
const normalized = normalizeRoutingToken(String(value || ''));
if (
normalized === 'per-channel-peer' ||
normalized === 'per-linked-identity'
) {
return normalized;
}
return fallback;
}
export function normalizeIdentityLinkAlias(
channelKind: string,
peerId: string,
): string {
const normalizedChannelKind = normalizeRoutingToken(channelKind);
const normalizedPeerId = normalizeRoutingToken(peerId);
if (!normalizedChannelKind || !normalizedPeerId) {
return '';
}
return `${normalizedChannelKind}:${normalizedPeerId}`;
}
export function normalizeSessionIdentityLinks(
value: unknown,
): Record<string, string[]> {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
return {};
}
const normalized: Record<string, string[]> = {};
for (const [rawIdentity, rawAliases] of Object.entries(value)) {
const identity = normalizeRoutingToken(rawIdentity);
if (!identity || !Array.isArray(rawAliases)) continue;
const aliases = [
...new Set(
rawAliases
.map((entry) => normalizeRoutingToken(String(entry || '')))
.filter(Boolean),
),
];
if (aliases.length === 0) continue;
normalized[identity] = aliases;
}
return normalized;
}
export function resolveLinkedSessionIdentity(
specificSessionKey: string,
config: SessionRoutingConfig,
): string | undefined {
const parsed = parseSessionKey(specificSessionKey);
if (!parsed || parsed.chatType !== 'dm') return undefined;
const alias = normalizeIdentityLinkAlias(parsed.channelKind, parsed.peerId);
if (!alias) return undefined;
for (const [identity, aliases] of Object.entries(config.identityLinks)) {
if (aliases.includes(alias)) {
return identity;
}
}
return undefined;
}
export function resolveSessionRoutingScope(
specificSessionKey: string,
config: SessionRoutingConfig,
): ResolvedSessionRoutingScope {
const parsed = parseSessionKey(specificSessionKey);
if (!parsed || parsed.chatType !== 'dm') {
return { mainSessionKey: specificSessionKey };
}
if (config.dmScope === 'per-channel-peer') {
return { mainSessionKey: specificSessionKey };
}
const linkedIdentity = resolveLinkedSessionIdentity(
specificSessionKey,
config,
);
if (!linkedIdentity) {
return { mainSessionKey: specificSessionKey };
}
return {
mainSessionKey: buildSessionKey(
parsed.agentId,
'main',
'dm',
linkedIdentity,
),
linkedIdentity,
};
}