forked from PinSpace-Org/GistPin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpagination.helper.ts
More file actions
55 lines (51 loc) 路 1.33 KB
/
Copy pathpagination.helper.ts
File metadata and controls
55 lines (51 loc) 路 1.33 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
export interface PaginatedResponse<T> {
data: T[];
pagination: {
count: number;
cursor: string | null;
hasMore: boolean;
};
}
export class PaginationHelper {
/**
* Encode a Date into a base64 cursor string.
*/
static encodeCursor(date: Date): string {
return Buffer.from(date.toISOString()).toString('base64');
}
/**
* Decode a base64 cursor string back to an ISO date string.
* Returns null if the cursor is invalid.
*/
static decodeCursor(cursor: string): string | null {
try {
const decoded = Buffer.from(cursor, 'base64').toString('utf8');
// Validate it parses as a date
const date = new Date(decoded);
if (isNaN(date.getTime())) return null;
return decoded;
} catch {
return null;
}
}
/**
* Build a paginated response from a list of items.
* The last item's created_at is used as the next cursor.
*/
static buildResponse<T extends { created_at: Date }>(
items: T[],
limit: number,
): PaginatedResponse<T> {
const hasMore = items.length === limit;
const lastItem = items[items.length - 1];
const cursor = hasMore && lastItem ? PaginationHelper.encodeCursor(lastItem.created_at) : null;
return {
data: items,
pagination: {
count: items.length,
cursor,
hasMore,
},
};
}
}