Skip to content

Commit

Permalink
feat: allow listing more than 150 odometer readings (#65)
Browse files Browse the repository at this point in the history
* feat: allow listing more than 150 odometer readings

* improve docstring

* feat: run queries sequetially
  • Loading branch information
braaar authored Dec 13, 2023
1 parent f21a8ee commit e66e8fa
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 24 deletions.
82 changes: 59 additions & 23 deletions src/abax-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,35 +142,42 @@ export class AbaxClient {
return { items: expenses.flatMap(expense => expense.items) };
}

/** Gets odometer values of trips. Required scopes: `abax_profile`, `open_api`, `open_api.trips`.*/
async getOdometerValuesOfTrips(
input: GetOdometerValuesOfTripsInput,
): Promise<GetOdometerValuesOfTripsResponse> {
// TODO: batch trips in batches of 150 (max allowed per query), similar to listTripExpenses
if (input.query.trip_ids.length > 150) {
throw new Error(
'Cannot get odometer values of more than 150 trips at once',
);
const tripIdBatches = input.query.trip_ids.reduce<string[][]>(
(batches, tripId) => {
const currentBatchIndex = batches.length - 1;

if (batches[currentBatchIndex]?.length === 150) {
batches.push([tripId]);
} else if (batches[currentBatchIndex]) {
batches[currentBatchIndex]?.push(tripId);
} else {
batches[currentBatchIndex] = [tripId];
}

return batches;
},
[[]],
);

const odometerValues: GetOdometerValuesOfTripsResponse['items'][] = [];

for (const batch of tripIdBatches) {
const response = await this.getOdometerValuesOf150Trips({
query: { trip_ids: batch },
});

odometerValues.push(response.items);
}
const call = this.buildCall()
.args<{ input: GetOdometerValuesOfTripsInput }>()
.method('get')
.path('v1/trips/odometerReadings')
.query(
({
input: {
query: { trip_ids },
},
}) => {
const params = new URLSearchParams();
trip_ids.forEach(trip => params.append('trip_ids', trip));
return params;
},
)
.parseJson(withZod(getOdometerValuesOfTripsResponseSchema))
.build();

return this.performRequest(apiKey => call({ input, apiKey }));
const items = odometerValues.flat(1);

return { items };
}

/** Gets equipment by ID. Required scopes: `abax_profile`, `open_api`, `open_api.equipment` */
getEquipment(input: GetEquipmentInput): Promise<GetEquipmentResponse> {
const call = this.buildCall()
Expand Down Expand Up @@ -277,6 +284,35 @@ export class AbaxClient {
return this.performRequest(apiKey => call({ input, apiKey }));
}

private async getOdometerValuesOf150Trips(
input: GetOdometerValuesOfTripsInput,
): Promise<GetOdometerValuesOfTripsResponse> {
if (input.query.trip_ids.length > 150) {
throw new Error(
'Cannot get odometer values of more than 150 trips at once',
);
}
const call = this.buildCall()
.args<{ input: GetOdometerValuesOfTripsInput }>()
.method('get')
.path('v1/trips/odometerReadings')
.query(
({
input: {
query: { trip_ids },
},
}) => {
const params = new URLSearchParams();
trip_ids.forEach(trip => params.append('trip_ids', trip));
return params;
},
)
.parseJson(withZod(getOdometerValuesOfTripsResponseSchema))
.build();

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

private makeApiUrl() {
if (this.config.environment === 'production' || !this.config.environment) {
return apiUrls.production;
Expand Down
2 changes: 1 addition & 1 deletion src/calls/get-odometer-values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { z } from 'zod';
import type { QueryEnvelope } from '../common/types.js';

export type GetOdometerValuesOfTripsInput = QueryEnvelope<{
/** Ids of trips. Can have up to 150 ids */
/** Ids of trips. */
trip_ids: string[];
}>;

Expand Down

0 comments on commit e66e8fa

Please sign in to comment.