1- import { createHash } from "node:crypto"
2-
3- import { serializeUrlSearchParams } from "@seamapi/url-search-params-serializer"
41import { sortBy } from "lodash"
52import { BadRequestException } from "nextlove"
63import { z } from "zod"
74
8- import { device , device_type } from "lib/zod/index.ts"
5+ import {
6+ device ,
7+ device_internal_page_cursor ,
8+ device_page_cursor ,
9+ device_type ,
10+ pagination ,
11+ } from "lib/zod/index.ts"
912
13+ import { getNextPageUrl , getPageCursorQueryHash } from "lib/api/pagination.ts"
1014import { withRouteSpec } from "lib/middleware/with-route-spec.ts"
1115import { getManagedDevicesWithFilter } from "lib/util/devices.ts"
1216
@@ -18,38 +22,16 @@ export const common_params = z.object({
1822 device_types : z . array ( device_type ) . optional ( ) ,
1923 manufacturer : z . string ( ) . optional ( ) ,
2024 limit : z . coerce . number ( ) . int ( ) . positive ( ) . default ( 500 ) ,
21- page_cursor : z
22- . string ( )
23- . base64 ( )
24- . optional ( )
25- . nullable ( )
26- . transform ( ( page_cursor ) => {
27- if ( page_cursor == null ) return page_cursor
28- return page_cursor_schema . parse (
29- JSON . parse ( Buffer . from ( page_cursor , "base64" ) . toString ( "utf8" ) ) ,
30- )
31- } ) ,
25+ page_cursor : device_page_cursor ,
3226} )
3327
34- const page_cursor_schema = z . tuple ( [
35- z . string ( ) ,
36- z . object ( {
37- created_at : z . coerce . date ( ) ,
38- device_id : z . string ( ) ,
39- } ) ,
40- ] )
41-
4228export default withRouteSpec ( {
4329 auth : [ "console_session_with_workspace" , "client_session" , "api_key" ] ,
4430 methods : [ "GET" , "POST" ] ,
4531 commonParams : common_params ,
4632 jsonResponse : z . object ( {
4733 devices : z . array ( device ) ,
48- pagination : z . object ( {
49- has_next_page : z . boolean ( ) ,
50- next_page_cursor : z . string ( ) . base64 ( ) . nullable ( ) ,
51- next_page_url : z . string ( ) . url ( ) . nullable ( ) ,
52- } ) ,
34+ pagination,
5335 } ) ,
5436} as const ) ( async ( req , res ) => {
5537 const { page_cursor, ...params } = req . commonParams
@@ -111,7 +93,7 @@ export default withRouteSpec({
11193
11294 let next_page_cursor = null
11395 if ( has_next_page ) {
114- const next_page_cursor_data = page_cursor_schema . parse ( [
96+ const next_page_cursor_data = device_internal_page_cursor . parse ( [
11597 query_hash ,
11698 {
11799 device_id : next_device . device_id ,
@@ -131,31 +113,3 @@ export default withRouteSpec({
131113 pagination : { has_next_page, next_page_cursor, next_page_url } ,
132114 } )
133115} )
134-
135- const getNextPageUrl = (
136- next_page_cursor : string | null ,
137- {
138- req,
139- } : {
140- req : {
141- url ?: string
142- commonParams : Record < string , unknown >
143- baseUrl : string | undefined
144- }
145- } ,
146- ) : string | null => {
147- if ( req . url == null || req . baseUrl == null ) return null
148- if ( next_page_cursor == null ) return null
149- const { page_cursor, ...params } = req . commonParams
150- const query = serializeUrlSearchParams ( params )
151- const url = new URL ( [ req . baseUrl , req . url ] . join ( "" ) )
152- url . search = query
153- url . searchParams . set ( "next_page_cursor" , next_page_cursor )
154- url . searchParams . sort ( )
155- return url . toString ( )
156- }
157-
158- const getPageCursorQueryHash = ( params : Record < string , unknown > ) : string => {
159- const query = serializeUrlSearchParams ( params )
160- return createHash ( "sha256" ) . update ( query ) . digest ( "hex" )
161- }
0 commit comments