first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
package schemas
import (
"encoding/base64"
"encoding/json"
"fmt"
)
// SerialCursor tracks pagination state for serial key exhaustion.
// When paginating across multiple keys, we exhaust all pages from one key
// before moving to the next, ensuring only one API call per pagination request.
type SerialCursor struct {
Version int `json:"v"` // Version for compatibility
KeyIndex int `json:"i"` // Current key index in sorted keys array
Cursor string `json:"c"` // Native cursor for current key (empty = start fresh)
}
// EncodeSerialCursor encodes a SerialCursor to a base64 string for transport.
func EncodeSerialCursor(cursor *SerialCursor) string {
if cursor == nil {
return ""
}
data, err := json.Marshal(cursor)
if err != nil {
return ""
}
return base64.URLEncoding.EncodeToString(data)
}
// DecodeSerialCursor decodes a base64 string back to a SerialCursor.
// Returns (nil, nil) if the encoded string is empty; returns an error for invalid data.
func DecodeSerialCursor(encoded string) (*SerialCursor, error) {
if encoded == "" {
return nil, nil
}
data, err := base64.URLEncoding.DecodeString(encoded)
if err != nil {
return nil, fmt.Errorf("failed to decode cursor: %w", err)
}
var cursor SerialCursor
if err := json.Unmarshal(data, &cursor); err != nil {
return nil, fmt.Errorf("failed to unmarshal cursor: %w", err)
}
// Validate version
if cursor.Version != 1 {
return nil, fmt.Errorf("unsupported cursor version: %d", cursor.Version)
}
return &cursor, nil
}
// NewSerialCursor creates a new SerialCursor with version 1.
func NewSerialCursor(keyIndex int, cursor string) *SerialCursor {
return &SerialCursor{
Version: 1,
KeyIndex: keyIndex,
Cursor: cursor,
}
}