From 3309850063943bfca50738596ced1fe06a30675c Mon Sep 17 00:00:00 2001 From: Nicolas Ayral Seydoux Date: Wed, 18 Dec 2024 14:28:00 +0100 Subject: [PATCH] Add async iterator for query results --- e2e/node/e2e.test.ts | 15 +++++++++++++++ src/gConsent/index.ts | 1 + src/gConsent/query/query.ts | 19 +++++++++++++++++++ src/index.ts | 1 + 4 files changed, 36 insertions(+) diff --git a/e2e/node/e2e.test.ts b/e2e/node/e2e.test.ts index 0eaf187d..6b4708c2 100644 --- a/e2e/node/e2e.test.ts +++ b/e2e/node/e2e.test.ts @@ -87,6 +87,7 @@ import { getPurposes, } from "../../src/common/getters"; import { toBeEqual } from "../../src/gConsent/util/toBeEqual.mock"; +import { paginateQuery } from "../../src/gConsent/query/query"; const { namedNode } = DataFactory; @@ -1768,4 +1769,18 @@ describe(`End-to-end access grant tests for environment [${environment}] `, () = ); }); }); + + it.only("can iterate through pages", async () => { + const pages = paginateQuery( + {}, + { + fetch: addUserAgent(requestorSession.fetch, TEST_USER_AGENT), + // FIXME add query endpoint discovery check. + queryEndpoint: new URL("query", vcProvider), + }, + ); + for await (const page of pages) { + expect(page.items).not.toHaveLength(0); + } + }); }); diff --git a/src/gConsent/index.ts b/src/gConsent/index.ts index c02b5f3e..26b19de7 100644 --- a/src/gConsent/index.ts +++ b/src/gConsent/index.ts @@ -52,6 +52,7 @@ export { CredentialType, DURATION, query, + paginateQuery, } from "./query/query"; export { diff --git a/src/gConsent/query/query.ts b/src/gConsent/query/query.ts index cb87fd3a..25803848 100644 --- a/src/gConsent/query/query.ts +++ b/src/gConsent/query/query.ts @@ -260,3 +260,22 @@ export async function query( } return toCredentialResult(response); } + +export async function* paginateQuery( + filter: CredentialFilter, + options: { + fetch: typeof fetch; + queryEndpoint: URL; + }, +) { + let page = await query(filter, options); + while (page.next !== undefined) { + yield page; + // This is a generator, so we don't want to go through + // all the pages at once with a Promise.all approach. + // eslint-disable-next-line no-await-in-loop + page = await query(page.next, options); + } + // Return the last page. + yield page; +} diff --git a/src/index.ts b/src/index.ts index a1d0d1bc..646e714f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -60,6 +60,7 @@ export { getAccessManagementUi, getAccessRequestFromRedirectUrl, issueAccessRequest, + paginateQuery, query, redirectToAccessManagementUi, redirectToRequestor,