diff --git a/.stats.yml b/.stats.yml index bbef6e28..c59f8103 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ -configured_endpoints: 93 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-94ab316666bc8401703576710fe5ef92b9bd7ca34e5eb6b0cc6ef44060afd4f5.yml +configured_endpoints: 94 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-ed05a916073da77a6014b00356582dee89a933b8fdba6370fa53767338516e45.yml diff --git a/api.md b/api.md index edaa2837..c5523a34 100644 --- a/api.md +++ b/api.md @@ -170,6 +170,16 @@ Methods: - client.events.backfills.fetch(backfillId) -> BackfillFetchResponse - client.events.backfills.revert(backfillId) -> BackfillRevertResponse +## Volume + +Types: + +- EventVolumes + +Methods: + +- client.events.volume.list({ ...params }) -> EventVolumes + # InvoiceLineItems Types: diff --git a/src/resources/events/events.ts b/src/resources/events/events.ts index 2f83ca18..5b5f94b1 100644 --- a/src/resources/events/events.ts +++ b/src/resources/events/events.ts @@ -4,9 +4,11 @@ import { APIResource } from '../../resource'; import * as Core from '../../core'; import * as EventsAPI from './events'; import * as BackfillsAPI from './backfills'; +import * as VolumeAPI from './volume'; export class Events extends APIResource { backfills: BackfillsAPI.Backfills = new BackfillsAPI.Backfills(this._client); + volume: VolumeAPI.Volume = new VolumeAPI.Volume(this._client); /** * This endpoint is used to amend a single usage event with a given `event_id`. @@ -577,4 +579,7 @@ export namespace Events { export import BackfillListResponsesPage = BackfillsAPI.BackfillListResponsesPage; export import BackfillCreateParams = BackfillsAPI.BackfillCreateParams; export import BackfillListParams = BackfillsAPI.BackfillListParams; + export import Volume = VolumeAPI.Volume; + export import EventVolumes = VolumeAPI.EventVolumes; + export import VolumeListParams = VolumeAPI.VolumeListParams; } diff --git a/src/resources/events/index.ts b/src/resources/events/index.ts index 05e63bf1..4e7c3138 100644 --- a/src/resources/events/index.ts +++ b/src/resources/events/index.ts @@ -21,3 +21,4 @@ export { EventSearchParams, Events, } from './events'; +export { EventVolumes, VolumeListParams, Volume } from './volume'; diff --git a/src/resources/events/volume.ts b/src/resources/events/volume.ts new file mode 100644 index 00000000..2d028a42 --- /dev/null +++ b/src/resources/events/volume.ts @@ -0,0 +1,90 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import * as VolumeAPI from './volume'; + +export class Volume extends APIResource { + /** + * This endpoint returns the event volume for an account in a + * [paginated list format](../reference/pagination). + * + * The event volume is aggregated by the hour and the + * [timestamp](../reference/ingest#determining-event-timestamp) field is used to + * determine which hour an event is associated with. Note, this means that + * late-arriving events increment the volume count for the hour window the + * timestamp is in, not the latest hour window. + * + * Each item in the response contains the count of events aggregated by the hour + * where the start and end time are hour-aligned and in UTC. When a specific + * timestamp is passed in for either start or end time, the response includes the + * hours the timestamp falls in. + */ + list(query?: VolumeListParams, options?: Core.RequestOptions): Core.APIPromise; + list(options?: Core.RequestOptions): Core.APIPromise; + list( + query: VolumeListParams | Core.RequestOptions = {}, + options?: Core.RequestOptions, + ): Core.APIPromise { + if (isRequestOptions(query)) { + return this.list({}, query); + } + return this._client.get('/events/volume', { query, ...options }); + } +} + +export interface EventVolumes { + data: Array; +} + +export namespace EventVolumes { + /** + * An EventVolume contains the event volume ingested in an hourly window. The + * timestamp used for the aggregation is the `timestamp` datetime field on events. + */ + export interface Data { + /** + * The number of events ingested with a timestamp between the timeframe + */ + count: number; + + timeframe_end: string; + + timeframe_start: string; + } +} + +export interface VolumeListParams { + /** + * Cursor for pagination. This can be populated by the `next_cursor` value returned + * from the initial request. + */ + cursor?: string | null; + + /** + * The number of items to fetch. Defaults to 20. + */ + limit?: number; + + /** + * The end of the timeframe, exclusive, in which to return event volume. If not + * specified, the current time is used. All datetime values are converted to UTC + * time.If the specified time isn't hour-aligned, the response includes the event + * volumecount for the hour the time falls in. + */ + timeframe_end?: string; + + /** + * The start of the timeframe, inclusive, in which to return event volume. All + * datetime values are converted to UTC time. If the specified time isn't + * hour-aligned, the response includes the event volume count for the hour the time + * falls in. + */ + timeframe_start?: string; +} + +export namespace Volume { + export import EventVolumes = VolumeAPI.EventVolumes; + export import VolumeListParams = VolumeAPI.VolumeListParams; +} diff --git a/tests/api-resources/events/volume.test.ts b/tests/api-resources/events/volume.test.ts new file mode 100644 index 00000000..495cbefd --- /dev/null +++ b/tests/api-resources/events/volume.test.ts @@ -0,0 +1,44 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Orb from 'orb-billing'; +import { Response } from 'node-fetch'; + +const client = new Orb({ + apiKey: 'My API Key', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource volume', () => { + test('list', async () => { + const responsePromise = client.events.volume.list(); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('list: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect(client.events.volume.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + Orb.NotFoundError, + ); + }); + + test('list: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.events.volume.list( + { + cursor: 'cursor', + limit: 1, + timeframe_end: '2019-12-27T18:11:19.117Z', + timeframe_start: '2019-12-27T18:11:19.117Z', + }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(Orb.NotFoundError); + }); +});