Skip to content

Commit

Permalink
feat: depaginated trips query (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
braaar authored Mar 6, 2024
1 parent a44bf7e commit 0a62750
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 21 deletions.
70 changes: 50 additions & 20 deletions src/abax-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
import {
type ListTripsInput,
type ListTripsResponse,
type Trip,
listTripsResponseSchema,
} from './calls/list-trips.js';
import {
Expand Down Expand Up @@ -94,27 +95,14 @@ export class AbaxClient {
return this.performRequest(apiKey => call({ input, apiKey }));
}

/** Gets paged list of Trips. Required scopes: `abax_profile`, `open_api`, `open_api.trips`. */
listTrips(input: ListTripsInput): Promise<ListTripsResponse> {
const call = this.authenticatedCall()
.args<{ input: ListTripsInput }>()
.method('get')
.path('v1/trips')
.query(({ input }) =>
makeQuery({
query: {
page: input.query.page,
page_size: input.query.page_size,
date_from: format(input.query.date_from, 'yyyy-MM-dd'),
date_to: format(input.query.date_to, 'yyyy-MM-dd'),
vehicle_id: input.query.vehicle_id,
},
}),
)
.parseJson(withZod(listTripsResponseSchema))
.build();
async listTrips(input: ListTripsInput): Promise<ListTripsResponse> {
if (input.query.page_size === 0) {
const trips = await this.listNextPagesOfTrips(input, 1);

return this.performRequest(apiKey => call({ input, apiKey }));
return { page: 1, page_size: 0, items: trips };
}

return this.listTripsPage(input);
}

listUsageSummary(
Expand Down Expand Up @@ -325,6 +313,48 @@ export class AbaxClient {
return this.performRequest(apiKey => call({ input, apiKey }));
}

/** Recursively list all pages starting from the provided page number. Uses page size 1500 (maximum). */
private async listNextPagesOfTrips(
input: { query: Omit<ListTripsInput['query'], 'page' | 'page_size'> },
page: number,
): Promise<Trip[]> {
const response = await this.listTripsPage({
query: { ...input.query, page_size: 1500, page },
});

if (response.items.length >= 1500) {
// There might be more trips, we need to fetch the next page
const nextPage = await this.listNextPagesOfTrips(input, page + 1);
return [...response.items, ...nextPage];
} else {
// There are less than 1500 trips, so this is the last page
return response.items;
}
}

/** Gets paged list of Trips. Required scopes: `abax_profile`, `open_api`, `open_api.trips`. */
private listTripsPage(input: ListTripsInput): Promise<ListTripsResponse> {
const call = this.authenticatedCall()
.args<{ input: ListTripsInput }>()
.method('get')
.path('v1/trips')
.query(({ input }) =>
makeQuery({
query: {
page: input.query.page,
page_size: input.query.page_size,
date_from: format(input.query.date_from, 'yyyy-MM-dd'),
date_to: format(input.query.date_to, 'yyyy-MM-dd'),
vehicle_id: input.query.vehicle_id,
},
}),
)
.parseJson(withZod(listTripsResponseSchema))
.build();

return this.performRequest(apiKey => call({ input, apiKey }));
}

private async getOdometerValuesOf150Trips(
input: GetOdometerValuesOfTripsInput,
): Promise<GetOdometerValuesOfTripsResponse> {
Expand Down
2 changes: 1 addition & 1 deletion src/calls/list-trips.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export type ListTripsInput = QueryEnvelope<{
/** Defaults to 1 */
page?: number;

/** Defaults to 1500 */
/** Defaults to 1500, if set to 0, all trips will be returned unpaginated */
page_size?: number;

/** The period cannot be longer than 3 months */
Expand Down

0 comments on commit 0a62750

Please sign in to comment.