/**
 * Copyright (c) 2020, 2021 Oracle and/or its affiliates.  All rights reserved.
 * This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
 */ interface hasLimit { limit ? : number ; } interface hasPage { page ? : string ; } interface hasStart { start ? : string ; } type Request = hasPage | hasStart ; async function * genericPaginate < ListRequest extends hasLimit , ListResponse , TResult extends { items ? : [ ] ; listObjects ? : { objects ? : [ ] ; } ; } > ( request , listCall , getNextPageToken , setNextPageToken , getResults , limitedRecord ? ) { let iteration = 0 ; const pageSize = request . limit || 0 ; if ( limitedRecord && pageSize ) { request . limit = Math . min ( limitedRecord , pageSize ) ; } else if ( limitedRecord ) { request . limit = limitedRecord ; } while ( true ) { if ( limitedRecord === 0 ) return ; if ( request . limit && limitedRecord ) { let recordsRemaining = limitedRecord - iteration ; if ( request . limit > recordsRemaining ) { request . limit = recordsRemaining ; } } const response = await listCall ( request ) ; for ( const result of getResults ( response ) ) { if ( result . items && result . items . length > 0 ) { iteration += result . items . length ; } else if ( result . listObjects && result . listObjects . objects ) { iteration += result . listObjects . objects . length ; } else { iteration ++ ; } yield result ; if ( limitedRecord && iteration > limitedRecord - 1 ) { return ; } } const nextPageToken = getNextPageToken ( response ) ; if ( ! nextPageToken ) { break ; } setNextPageToken ( request , nextPageToken ) ; } } export function genericPaginateRecords < ListRequest , ListResponse , ItemSummary > ( request , listCall , getNextPageToken , setNextPageToken , getItems , limitedRecord ? ) { return genericPaginate ( request , listCall , getNextPageToken , setNextPageToken , getItems , limitedRecord ) ; } export function paginateRecords < ListRequest extends Request , ListResponse , ItemSummary = any > ( request , listCall , limitedRecord ? ) { return genericPaginateRecords ( request , listCall , res => findNextPageToken ( res ) , ( req , nextPageToken ) => findSetPageToken ( req , nextPageToken ) , res => findResult ( res ) , limitedRecord ) ; } export function genericPaginateResponses < ListRequest , ListResponse > ( request , listCall , getNextPageToken , setNextPageToken , limitedRecord ? ) { return genericPaginate ( request , listCall , getNextPageToken , setNextPageToken , res => [ res ] , limitedRecord ) ; } export function paginateResponses < ListRequest extends Request , ListResponse > ( request , listCall , limitedRecord ? ) { return genericPaginateResponses ( request , listCall , response => findNextPageToken ( response ) , ( req , nextPageToken ) => findSetPageToken ( req , nextPageToken ) , limitedRecord ) ; } export async function paginatedRecordsWithLimit < ListRequest extends Request , ListResponse > ( request , listCall , limitedRecord ? ) { const records = [ ] ; const response = paginateRecords ( request , listCall , limitedRecord ) ; let record = await response . next ( ) ; while ( record . done === false ) { records . push ( record ) ; record = await response . next ( ) ; } return records ; } export async function paginatedResponsesWithLimit < ListRequest extends Request , ListResponse > ( request , listCall , limitedRecord ? ) { let records = [ ] ; const response = await paginateResponses ( request , listCall , limitedRecord ) ; let iterator = await response . next ( ) ; let record = iterator . value ; while ( iterator . done === false ) { record = iterator . value ; records . push ( record ) ; iterator = await response . next ( ) ; } return records ; } function findNextPageToken ( res ) { if ( "listObjects" in res ) { return res . listObjects . nextStartWith ; } return res . opcNextPage ; } function findSetPageToken ( req , nextPageToken ) { if ( req . start ) { req . start = nextPageToken ; } else { req . page = nextPageToken ; } } function findResult ( res ) { if ( res . listObjects && res . listObjects . objects ) { return res . listObjects . objects ; } return res . items ; }