code: function getSyncPage (http, items, query, { paginate }) {
    if (query.nextSyncToken) {
      query.sync_token = query.nextSyncToken
      delete query.nextSyncToken
    }
  
    if (query.nextPageToken) {
      query.sync_token = query.nextPageToken
      delete query.nextPageToken
    }
  
    if (query.sync_token) {
      delete query.initial
      delete query.type
      delete query.content_type
    }
  
    return http.get('sync', createRequestConfig({query: query}))
      .then((response) => {
        const data = response.data
        items = items.concat(data.items)
        if (data.nextPageUrl) {
          if (paginate) {
            delete query.initial
            query.sync_token = getToken(data.nextPageUrl)
            return getSyncPage(http, items, query, { paginate })
          }
          return {
            items: items,
            nextPageToken: getToken(data.nextPageUrl)
          }
        } else if (data.nextSyncUrl) {
          return {
            items: items,
            nextSyncToken: getToken(data.nextSyncUrl)
          }
        }
      })
  }
docs: If the response contains a nextPageUrl, extracts the sync token to get the
  next page and calls itself again with that token.
  Otherwise, if the response contains a nextSyncUrl, extracts the sync token
  and returns it.
  On each call of this function, any retrieved items are collected in the
  supplied items array, which gets returned in the end
  @private
  @param {Object} http
  @param {Array<Entities.Entry|Entities.Array|Sync.DeletedEntry|Sync.DeletedAsset>} items
  @param {Object} query
  @param {Object} options - Sync page options object
  @param {boolean} [options.paginate = true] - If further sync pages should automatically be crawled
  @return {Promise<{items: Array, nextSyncToken: string}>}