diff --git a/shared-libs/cht-datasource/src/index.ts b/shared-libs/cht-datasource/src/index.ts index 377e39a609..c7907aca5b 100644 --- a/shared-libs/cht-datasource/src/index.ts +++ b/shared-libs/cht-datasource/src/index.ts @@ -97,7 +97,7 @@ export const getDatasource = (ctx: DataContext) => { * @throws Error if the provided skip is `< 0` */ getPage: (personType: string, limit = 100, skip = 0) => ctx.bind(Person.v1.getPage)( - Qualifier.byContactType(personType), limit, skip + { personType: Qualifier.byContactType(personType), limit, skip } ), /** diff --git a/shared-libs/cht-datasource/src/libs/data-context.ts b/shared-libs/cht-datasource/src/libs/data-context.ts index d11820b201..4a11e2b9cf 100644 --- a/shared-libs/cht-datasource/src/libs/data-context.ts +++ b/shared-libs/cht-datasource/src/libs/data-context.ts @@ -40,20 +40,24 @@ export const adapt = ( return remote(context); }; +interface PaginationArgs { + limit: number; + skip: number; +} + +type FetchFunctionArgs> = PaginationArgs & TFields; + /** @internal */ -export const getDocumentStream = async function* ( - fetchFunction: (...args: Args) => Promise, - fetchFunctionArgs: { - limit: number; - skip: number; - } & Record -): AsyncGenerator { +export const getDocumentStream = async function* >( + fetchFunction: (args: FetchFunctionArgs) => Promise, + fetchFunctionArgs: FetchFunctionArgs +): AsyncGenerator { const { limit } = fetchFunctionArgs; let { skip } = fetchFunctionArgs; const hasMoreResults = () => skip && skip % limit === 0; do { - const docs = await fetchFunction(...(Object.values(fetchFunctionArgs) as Args)); + const docs = await fetchFunction(fetchFunctionArgs); for (const doc of docs) { yield doc; diff --git a/shared-libs/cht-datasource/src/person.ts b/shared-libs/cht-datasource/src/person.ts index 93e6b33014..7cfb336dbd 100644 --- a/shared-libs/cht-datasource/src/person.ts +++ b/shared-libs/cht-datasource/src/person.ts @@ -78,7 +78,11 @@ export namespace v1 { * @throws Error if the provided `limit` value is `<=0` * @throws Error if the provided `skip` value is `<0` */ - const curriedFn = async (personType: ContactTypeQualifier, limit = 100, skip = 0): Promise => { + const curriedFn = async ({personType, limit = 100, skip = 0}: { + personType: ContactTypeQualifier; + limit?: number; + skip?: number; + }): Promise => { assertTypeQualifier(personType); assertLimitAndSkip(limit, skip); @@ -133,7 +137,7 @@ export namespace v1 { const getPage = context.bind(v1.getPage); const limit = 100; const skip = 0; - yield* getDocumentStream(getPage, { personType, limit, skip }) as AsyncGenerator; + yield* getDocumentStream(getPage, { personType, limit, skip }); }; }; } diff --git a/shared-libs/cht-datasource/test/index.spec.ts b/shared-libs/cht-datasource/test/index.spec.ts index dd67e1c1ae..d6bd758254 100644 --- a/shared-libs/cht-datasource/test/index.spec.ts +++ b/shared-libs/cht-datasource/test/index.spec.ts @@ -139,7 +139,7 @@ describe('CHT Script API - getDatasource', () => { expect(returnedPeople).to.equal(expectedPeople); expect(dataContextBind.calledOnceWithExactly(Person.v1.getPage)).to.be.true; - expect(personGetPage.calledOnceWithExactly(personTypeQualifier, limit, skip)).to.be.true; + expect(personGetPage.calledOnceWithExactly({ personType: personTypeQualifier, limit, skip })).to.be.true; expect(byContactType.calledOnceWithExactly(personType)).to.be.true; }); diff --git a/shared-libs/cht-datasource/test/libs/data-context.spec.ts b/shared-libs/cht-datasource/test/libs/data-context.spec.ts index 14b9375985..82d57682e6 100644 --- a/shared-libs/cht-datasource/test/libs/data-context.spec.ts +++ b/shared-libs/cht-datasource/test/libs/data-context.spec.ts @@ -140,7 +140,7 @@ describe('context lib', () => { } expect(results).to.deep.equal(mockDocs); - expect(fetchFunctionStub.calledOnceWithExactly(...Object.values(args))).to.be.true; + expect(fetchFunctionStub.calledOnceWithExactly(args)).to.be.true; }); it('should handle multiple pages', async () => { @@ -159,8 +159,8 @@ describe('context lib', () => { expect(results).to.deep.equal([...mockDocs1, ...mockDocs2]); expect(fetchFunctionStub.callCount).to.equal(2); - expect(fetchFunctionStub.firstCall.args).to.deep.equal([2, 0]); - expect(fetchFunctionStub.secondCall.args).to.deep.equal([2, 0]); + expect(fetchFunctionStub.firstCall.args).to.deep.equal([{ limit: 2, skip: 0 }]); + expect(fetchFunctionStub.secondCall.args).to.deep.equal([{ limit: 2, skip: 0 }]); }); it('should handle empty result', async () => { diff --git a/shared-libs/cht-datasource/test/person.spec.ts b/shared-libs/cht-datasource/test/person.spec.ts index a7dc144ae1..d6013c5f29 100644 --- a/shared-libs/cht-datasource/test/person.spec.ts +++ b/shared-libs/cht-datasource/test/person.spec.ts @@ -145,7 +145,7 @@ describe('person', () => { isContactTypeQualifier.returns(true); getPage.resolves(people); - const result = await Person.v1.getPage(dataContext)(personTypeQualifier, limit, skip); + const result = await Person.v1.getPage(dataContext)({ personType: personTypeQualifier, limit, skip }); expect(result).to.equal(people); expect(assertDataContext.calledOnceWithExactly(dataContext)).to.be.true; @@ -169,7 +169,7 @@ describe('person', () => { it('throws an error if the qualifier is invalid', async () => { isContactTypeQualifier.returns(false); - await expect(Person.v1.getPage(dataContext)(invalidQualifier)) + await expect(Person.v1.getPage(dataContext)({personType: invalidQualifier})) .to.be.rejectedWith(`Invalid type [${JSON.stringify(invalidQualifier)}].`); expect(assertDataContext.calledOnceWithExactly(dataContext)).to.be.true; @@ -182,7 +182,7 @@ describe('person', () => { isContactTypeQualifier.returns(true); getPage.resolves(people); - await expect(Person.v1.getPage(dataContext)(personTypeQualifier, invalidLimit, skip)) + await expect(Person.v1.getPage(dataContext)({ personType: personTypeQualifier, limit: invalidLimit, skip })) .to.be.rejectedWith(`limit must be a positive number`); expect(assertDataContext.calledOnceWithExactly(dataContext)).to.be.true; @@ -195,8 +195,11 @@ describe('person', () => { isContactTypeQualifier.returns(true); getPage.resolves(people); - await expect(Person.v1.getPage(dataContext)(personTypeQualifier, limit, invalidSkip)) - .to.be.rejectedWith(`skip must be a non-negative number`); + await expect(Person.v1.getPage(dataContext)({ + personType: personTypeQualifier, + limit: limit, + skip: invalidSkip + })).to.be.rejectedWith(`skip must be a non-negative number`); expect(assertDataContext.calledOnceWithExactly(dataContext)).to.be.true; expect(adapt.calledOnceWithExactly(dataContext, Local.Person.v1.getPage, Remote.Person.v1.getPage)).to.be.true;