
    +j!                    $   S r SSKJr  SSKrSSKrSSKJr  SSKJrJr  SSK	J
r
Jr   " S S\5      rS	rS
rSr\" SS9 " S S5      5       rSrSSS jjrSSS jjr S       SS jjrS S jrS!S jr\" SSS\R0                  S9rS"S jrS#S jrg)$u  Opaque keyset-pagination cursor for /api/assets.

Payload JSON uses short keys to keep the encoded length small:

    {"s": <sort_field>, "v": <value>, "id": <id>, "o": <order>}

The `o` key binds the cursor to the sort direction it was minted under,
so replaying a `desc` cursor against an `asc` request fails with
``INVALID_CURSOR`` rather than silently walking the wrong direction.
`o` is mandatory on every payload — a cursor without it is rejected as
malformed.

Encoding is base64url with no padding. Cursors are opaque tokens: the
payload format is internal to this server, and clients must treat a
cursor as a black box handed back via `next_cursor`. No byte-level
compatibility with any other implementation is required.

Time values are serialized as Unix microseconds (UTC) — microsecond
precision is sufficient to round-trip the timestamps stored by the
database without rounding rows in the same millisecond bucket.
    )annotationsN)	dataclass)datetimetimezone)IterableOptionalc                      \ rS rSrSrSrg)InvalidCursorError   zRaised on a malformed, oversized, or unsupported-sort-field cursor.

Map to a 400 response with code ``INVALID_CURSOR`` at the handler.
 N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       :/home/wildlama/comfy/ComfyUI/app/assets/services/cursor.pyr
   r
      s    r   r
   i    i      T)frozenc                  >    \ rS rSr% S\S'   S\S'   S\S'   S\S'   Srg)	CursorPayload:   str
sort_fieldvalueidorderr   N)r   r   r   r   __annotations__r   r   r   r   r   r   :   s    OJGJr   r   )ascdescc                   U[         ;  a  [        S[          SU< 35      eU(       d  [        S5      e[        U5      [        :  a  [        S5      e[        U5      [        :  a  [        S5      eXX#S.n[
        R                  " USSS	9n[        R                  " UR                  S
5      5      R                  S5      R                  S5      $ )a  Encode a cursor payload as a base64url (no-padding) string.

`order` binds the cursor to the sort direction it was minted under so a
later request with a flipped `order` query parameter is rejected with
``INVALID_CURSOR`` rather than silently walking the wrong direction.
zorder must be one of z, got zid must be non-emptyid exceeds maximum lengthvalue exceeds maximum length)svr   o),:F)
separatorsensure_asciizutf-8   =ascii)_VALID_ORDERSr
   lenMAX_CURSOR_ID_LENGTHMAX_CURSOR_VALUE_LENGTHjsondumpsbase64urlsafe_b64encodeencoderstripdecode)r   r   r   r   payloadraws         r   encode_cursorr;   E   s     M! #8veY!WXX  !788
2w%% !<==
5z++ !?@@"AG
**W%
HC ##CJJw$78??ELLWUUr   c                    UR                   c  [        S5      e[        UR                  [        R
                  5      5      n[        U [        U5      X#S9$ )zEncode a time-typed cursor at Unix microsecond precision.

Accepts an aware datetime (any timezone) and normalizes to UTC. Naive
datetimes are rejected so callers can't accidentally encode the local
wall-clock value of a UTC-stored timestamp.
z2encode_cursor_from_time requires an aware datetime)r   )tzinfo
ValueError_datetime_to_unix_micros
astimezoner   utcr;   r   )r   tr   r   micross        r   encode_cursor_from_timerD   _   sD     	xxMNN%all8<<&@AFS["BBr   c                t   [        U 5      [        :  a  [        S5      e S[        U 5      * S-  -  n[        R                  " X-   5      n [        R                  " U5      n[        U[        5      (       d  [        S5      eUR                  S5      nUR                  S	5      nUR                  S
5      n	UR                  S5      n
[        U[        5      (       a*  [        U[        5      (       a  [        U	[        5      (       d  [        S5      eU	S:X  a  [        S5      e[        U	5      [         :  a  [        S5      e[        U5      ["        :  a  [        S5      eXq;  a  [        SU< 35      e[        U
[        5      (       d  [        S5      eU
[$        ;  a  [        SU
< 35      eUb  X:w  a  [        SU
< SU< 35      e['        XxXS9$ ! [
        [        R                  R                  4 a  n[        SU 35      UeSnAff = f! [        R                  [        4 a  n[        SU 35      UeSnAff = f)u  Parse an opaque cursor.

``allowed_sort_fields`` is the endpoint's accepted sort-field list — a
cursor carrying a field outside this set is rejected so a cursor minted
for one column can't be replayed against another (e.g. a ``created_at``
timestamp string compared against a ``name`` column).

``expected_order`` (``"asc"``/``"desc"``), when supplied, must match the
payload's ``o`` field. ``o`` is required on every payload; a cursor
missing it is rejected as malformed.

Passing no allowed fields rejects every cursor.
zcursor exceeds maximum length=   z
encoding: Nz	payload: zpayload: expected objectr%   r&   r   r'   z%payload: missing or non-string s/v/id z
missing idr#   r$   zunsupported sort field zmissing or non-string ozunsupported order zcursor order z does not match request order )r   r   r   r   )r/   MAX_ENCODED_CURSOR_LENGTHr
   r4   urlsafe_b64decoder>   binasciiErrorr2   loadsJSONDecodeErrorUnicodeDecodeError
isinstancedictgetr   r0   r1   r.   r   )cursorallowed_sort_fieldsexpected_orderpaddingr:   edecodedr   r   r   r   s              r   decode_cursorrY   l   s   $ 6{.. !@AA: #f+)*&&v'789**S/ gt$$ !;<<S!JKKE	T	BKKEj#&&j.D.DJWY[^L_L_ !HII	Rx ..
2w%% !<==
5z++ !?@@, #::.!IJJeS!! !:;;M! #5eY!?@@!e&= E9$B>BTU
 	
 JPPM --. : :aS!129:
   "45 9 9QC1q89s/   *G H	 $H2HH	H7#H22H7c                    U c  [        S5      e [        U R                  5      n [	        U5      $ ! [         a  n[        SU 35      UeSnAff = f! [
        [        [        4 a  n[        SU 35      UeSnAff = f)zDParse a time-typed cursor value as Unix microseconds, returning UTC.Nnil cursor payloadz value is not a valid timestamp: z%value is out of representable range: )r
   intr   r>   _unix_micros_to_datetimeOverflowErrorOSError)r9   rC   rW   s      r   decode_cursor_timer`      s     !566PW]]#U'//  P #CA3!GHaOP 7J/ U !#H!LMSTTUs+   1 
A 
AA

AA;'A66A;c                    U c  [        S5      e [        U R                  5      $ ! [         a  n[        SU 35      UeSnAff = f)z*Parse a cursor value as a base-10 integer.Nr[   zvalue is not a valid integer: )r
   r\   r   r>   )r9   rW   s     r   decode_cursor_intrb      sO     !566N7==!! N #A!!EFAMNs   % 
A>Ai     )r=   c                l    U [         -
  nUR                  S-  UR                  -   S-  UR                  -   $ )zBConvert an aware UTC datetime to Unix microseconds (integer math).iQ @B )_EPOCHdayssecondsmicroseconds)rB   deltas     r   r?   r?      s3    JEJJ%--/9<u?Q?QQQr   c                ~    [        U S5      u  p[        R                  " U[        R                  S9R                  US9$ )zBConvert Unix microseconds to a UTC datetime, preserving precision.re   )tz)microsecond)divmodr   fromtimestampr   rA   replace)rC   rh   micro_remainders      r   r]   r]      s7    %fi8G!!'hll;CCP_C``r   )r!   )
r   r   r   r   r   r   r   r   returnr   )
r   r   rB   r   r   r   r   r   rr   r   )N)rS   r   rT   zIterable[str]rU   z
str | Nonerr   r   )r9   Optional[CursorPayload]rr   r   )r9   rs   rr   r\   )rB   r   rr   r\   )rC   r\   rr   r   )r   
__future__r   r4   r2   dataclassesr   r   r   typingr   r   r>   r
   rI   r1   r0   r   r.   r;   rD   rY   r`   rb   rA   rf   r?   r]   r   r   r   <module>rw      s   * #   ! ' % , !    $    V4
C  "&@Q@Q&@Q @Q 	@QFU N 
$1X\\	2Rar   