mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 21:20:57 +00:00
feat: setup the attachment to the passenger api
This commit is contained in:
52
apps/edr-passenger-api/src/modules/support/message-cursor.ts
Normal file
52
apps/edr-passenger-api/src/modules/support/message-cursor.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
|
||||
/**
|
||||
* Keyset cursor for paging a thread backwards from newest.
|
||||
*
|
||||
* The sort key is the pair `(createdAt, id)`, not `createdAt` alone: two
|
||||
* messages can share a millisecond, and a cursor on a non-unique key either
|
||||
* re-serves or skips the tied rows depending which side of the boundary they
|
||||
* land on. The id breaks ties with a stable total order.
|
||||
*
|
||||
* Deliberately a twin of the freight API's `message-cursor.ts`, not a shared
|
||||
* import: the two APIs share no runtime package, and @edr/types is Nest-free by
|
||||
* design (this throws Nest exceptions). The wire format matches so a client can
|
||||
* treat both chats identically — keep them in step if either changes.
|
||||
*/
|
||||
export interface MessageCursor {
|
||||
createdAt: Date;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export function encodeMessageCursor(cursor: MessageCursor): string {
|
||||
return Buffer.from(`${cursor.createdAt.toISOString()}|${cursor.id}`, 'utf8').toString(
|
||||
'base64url',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a client-supplied cursor. Rejects anything malformed rather than
|
||||
* silently falling back to "first page" — a corrupted cursor that degrades to
|
||||
* page 1 makes an infinite scroll loop forever over the same rows.
|
||||
*/
|
||||
export function decodeMessageCursor(raw: string): MessageCursor {
|
||||
let decoded: string;
|
||||
try {
|
||||
decoded = Buffer.from(raw, 'base64url').toString('utf8');
|
||||
} catch {
|
||||
throw new BadRequestException('Malformed pagination cursor.');
|
||||
}
|
||||
|
||||
const separator = decoded.lastIndexOf('|');
|
||||
if (separator === -1) {
|
||||
throw new BadRequestException('Malformed pagination cursor.');
|
||||
}
|
||||
|
||||
const createdAt = new Date(decoded.slice(0, separator));
|
||||
const id = decoded.slice(separator + 1);
|
||||
if (Number.isNaN(createdAt.getTime()) || !id) {
|
||||
throw new BadRequestException('Malformed pagination cursor.');
|
||||
}
|
||||
|
||||
return { createdAt, id };
|
||||
}
|
||||
Reference in New Issue
Block a user