fix: set In-Reply-To and References on replies #234
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* RFC 5322 §3.6.4 reply threading.
|
||||
*
|
||||
* Computes the In-Reply-To and References headers an outgoing reply must
|
||||
* carry so MUAs can stitch the conversation back together.
|
||||
*
|
||||
* In-Reply-To = parent.Message-ID
|
||||
* References = parent.References (if any) + parent.Message-ID
|
||||
*
|
||||
* Bare msg-ids only — angle brackets are stripped because JMAP RFC 8621
|
||||
* §4.1.2.3 stores Message-IDs without them.
|
||||
*/
|
||||
|
||||
export interface ParentThreadingInfo {
|
||||
// JMAP RFC 8621 §4.1.2.3 specifies messageId as String[]|null, but the
|
||||
// codebase has historically typed it as string. Accept either shape.
|
||||
messageId?: string | string[];
|
||||
references?: string[];
|
||||
}
|
||||
|
||||
export interface ReplyThreadingHeaders {
|
||||
inReplyTo: string[];
|
||||
references: string[];
|
||||
}
|
||||
|
||||
export function stripMessageIdBrackets(id: string): string {
|
||||
return id.trim().replace(/^<+/, '').replace(/>+$/, '').trim();
|
||||
}
|
||||
|
||||
export function computeReplyThreadingHeaders(
|
||||
parent: ParentThreadingInfo | undefined,
|
||||
): ReplyThreadingHeaders | null {
|
||||
const rawId = Array.isArray(parent?.messageId) ? parent.messageId[0] : parent?.messageId;
|
||||
const parentId = rawId ? stripMessageIdBrackets(rawId) : '';
|
||||
if (!parentId) return null;
|
||||
|
||||
const ancestors = (parent?.references ?? [])
|
||||
.map(stripMessageIdBrackets)
|
||||
.filter(Boolean);
|
||||
|
||||
// De-dupe while preserving order; the parent's id closes the chain.
|
||||
const seen = new Set<string>();
|
||||
const references: string[] = [];
|
||||
for (const id of [...ancestors, parentId]) {
|
||||
if (seen.has(id)) continue;
|
||||
seen.add(id);
|
||||
references.push(id);
|
||||
}
|
||||
|
||||
return { inReplyTo: [parentId], references };
|
||||
}
|
||||
Reference in New Issue
Block a user