@tiempo/sdk 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +269 -2
  3. package/dist/cjs/client.d.ts +24 -0
  4. package/dist/cjs/client.js +42 -0
  5. package/dist/cjs/core.d.ts +72 -0
  6. package/dist/cjs/core.js +187 -0
  7. package/dist/cjs/crypto.d.ts +5 -0
  8. package/dist/cjs/crypto.js +29 -0
  9. package/dist/cjs/errors.d.ts +86 -0
  10. package/dist/cjs/errors.js +134 -0
  11. package/dist/cjs/events.d.ts +23 -0
  12. package/dist/cjs/events.js +10 -0
  13. package/dist/cjs/generated/events.d.ts +51 -0
  14. package/dist/cjs/generated/events.js +51 -0
  15. package/dist/cjs/generated/meta.d.ts +4 -0
  16. package/dist/cjs/generated/meta.js +8 -0
  17. package/dist/cjs/generated/openapi.d.ts +3721 -0
  18. package/dist/cjs/generated/openapi.js +2 -0
  19. package/dist/cjs/generated/resources.d.ts +416 -0
  20. package/dist/cjs/generated/resources.js +621 -0
  21. package/dist/cjs/generated/types.d.ts +134 -0
  22. package/dist/cjs/generated/types.js +3 -0
  23. package/dist/cjs/index.d.ts +16 -0
  24. package/dist/cjs/index.js +49 -0
  25. package/dist/cjs/list.d.ts +43 -0
  26. package/dist/cjs/list.js +78 -0
  27. package/dist/cjs/package.json +1 -0
  28. package/dist/cjs/query.d.ts +8 -0
  29. package/dist/cjs/query.js +47 -0
  30. package/dist/cjs/shared.d.ts +7 -0
  31. package/dist/cjs/shared.js +2 -0
  32. package/dist/cjs/webhooks.d.ts +34 -0
  33. package/dist/cjs/webhooks.js +115 -0
  34. package/dist/esm/client.d.ts +24 -0
  35. package/dist/esm/client.js +38 -0
  36. package/dist/esm/core.d.ts +72 -0
  37. package/dist/esm/core.js +181 -0
  38. package/dist/esm/crypto.d.ts +5 -0
  39. package/dist/esm/crypto.js +26 -0
  40. package/dist/esm/errors.d.ts +86 -0
  41. package/dist/esm/errors.js +120 -0
  42. package/dist/esm/events.d.ts +23 -0
  43. package/dist/esm/events.js +8 -0
  44. package/dist/esm/generated/events.d.ts +51 -0
  45. package/dist/esm/generated/events.js +48 -0
  46. package/dist/esm/generated/meta.d.ts +4 -0
  47. package/dist/esm/generated/meta.js +5 -0
  48. package/dist/esm/generated/openapi.d.ts +3721 -0
  49. package/dist/esm/generated/openapi.js +1 -0
  50. package/dist/esm/generated/resources.d.ts +416 -0
  51. package/dist/esm/generated/resources.js +603 -0
  52. package/dist/esm/generated/types.d.ts +134 -0
  53. package/dist/esm/generated/types.js +2 -0
  54. package/dist/esm/index.d.ts +16 -0
  55. package/dist/esm/index.js +10 -0
  56. package/dist/esm/list.d.ts +43 -0
  57. package/dist/esm/list.js +74 -0
  58. package/dist/esm/package.json +1 -0
  59. package/dist/esm/query.d.ts +8 -0
  60. package/dist/esm/query.js +43 -0
  61. package/dist/esm/shared.d.ts +7 -0
  62. package/dist/esm/shared.js +1 -0
  63. package/dist/esm/webhooks.d.ts +34 -0
  64. package/dist/esm/webhooks.js +109 -0
  65. package/package.json +74 -4
@@ -0,0 +1,134 @@
1
+ import type { components, operations } from './openapi.js';
2
+ import type { WithMetadataFilter } from '../shared.js';
3
+ export type { components, operations };
4
+ export type Account = components["schemas"]["Account"];
5
+ export type Attendee = components["schemas"]["Attendee"];
6
+ export type AvailabilityCalendarBlocked = components["schemas"]["AvailabilityCalendarBlocked"];
7
+ export type AvailabilityCalendar = components["schemas"]["AvailabilityCalendarCalendar"];
8
+ export type AvailabilityCalendarDay = components["schemas"]["AvailabilityCalendarDay"];
9
+ export type AvailabilityCalendarDayReason = components["schemas"]["AvailabilityCalendarDayReason"];
10
+ export type AvailabilityCalendarFree = components["schemas"]["AvailabilityCalendarFree"];
11
+ export type AvailabilityCalendarResourceCalendar = components["schemas"]["AvailabilityCalendarResourceCalendar"];
12
+ export type AvailabilityCalendarWorking = components["schemas"]["AvailabilityCalendarWorking"];
13
+ export type Availability = components["schemas"]["AvailabilitySearchAvailability"];
14
+ export type AvailabilitySegmentQuery = components["schemas"]["AvailabilitySearchSegmentQuery"];
15
+ export type AvailabilitySlot = components["schemas"]["AvailabilitySearchSlot"];
16
+ export type AvailabilitySlotSegment = components["schemas"]["AvailabilitySearchSlotSegment"];
17
+ export type Block = components["schemas"]["Block"];
18
+ export type Booking = components["schemas"]["Booking"];
19
+ export type BookingSegment = components["schemas"]["BookingSegment"];
20
+ export type BookingsImportedBooking = components["schemas"]["BookingsImportedBooking"];
21
+ export type BookingsImportedSegment = components["schemas"]["BookingsImportedSegment"];
22
+ export type BookingSegmentInput = components["schemas"]["BookingsSegmentInput"];
23
+ export type CandidateConflict = components["schemas"]["CandidateConflict"];
24
+ export type Conflict = components["schemas"]["Conflict"];
25
+ export type ConflictPreview = components["schemas"]["ConflictPreview"];
26
+ export type ConflictPreviewAffected = components["schemas"]["ConflictPreviewAffected"];
27
+ export type DeletedObject = components["schemas"]["DeletedObject"];
28
+ export type Location = components["schemas"]["Location"];
29
+ export type Resource = components["schemas"]["Resource"];
30
+ export type Schedule = components["schemas"]["Schedule"];
31
+ export type ScheduleInterval = components["schemas"]["ScheduleInterval"];
32
+ export type ScheduleIntervalInput = components["schemas"]["ScheduleIntervalInput"];
33
+ export type ScheduleOverride = components["schemas"]["ScheduleOverride"];
34
+ export type Series = components["schemas"]["Series"];
35
+ export type SeriesTemplate = components["schemas"]["SeriesTemplate"];
36
+ export type SeriesTemplateInput = components["schemas"]["SeriesTemplateInput"];
37
+ export type SeriesTemplateSegment = components["schemas"]["SeriesTemplateSegment"];
38
+ export type SeriesTemplateSegmentInput = components["schemas"]["SeriesTemplateSegmentInput"];
39
+ export type SkippedOccurrence = components["schemas"]["SkippedOccurrence"];
40
+ export type AccountUsage = components["schemas"]["UsageAccountUsage"];
41
+ export type UsageStatement = components["schemas"]["UsageStatement"];
42
+ export type UsageSummary = components["schemas"]["UsageSummary"];
43
+ export type WebhookDelivery = components["schemas"]["WebhookDelivery"];
44
+ export type WebhookDeliveryAttempt = components["schemas"]["WebhookDeliveryAttempt"];
45
+ export type WebhookEndpoint = components["schemas"]["WebhookEndpoint"];
46
+ export type WebhookEndpointResendResult = components["schemas"]["WebhookResendsEndpointResent"];
47
+ /** Params for `list` on `accounts` (GET /v1/accounts). */
48
+ export type AccountListParams = WithMetadataFilter<NonNullable<operations["accounts.list"]["parameters"]["query"]>>;
49
+ /** Params for `create` on `accounts` (POST /v1/accounts). */
50
+ export type AccountCreateParams = NonNullable<operations["accounts.create"]["requestBody"]>["content"]["application/json"];
51
+ /** Params for `update` on `accounts` (POST /v1/accounts/{id}). */
52
+ export type AccountUpdateParams = NonNullable<operations["accounts.update"]["requestBody"]>["content"]["application/json"];
53
+ /** Params for `update` on `attendees` (POST /v1/attendees/{id}). */
54
+ export type AttendeeUpdateParams = NonNullable<operations["attendees.updateAttendee"]["requestBody"]>["content"]["application/json"];
55
+ /** Params for `cancel` on `attendees` (POST /v1/attendees/{id}/cancel). */
56
+ export type AttendeeCancelParams = NonNullable<operations["attendees.cancelAttendee"]["requestBody"]>["content"]["application/json"];
57
+ /** Params for `search` on `availability` (POST /v1/availability). */
58
+ export type AvailabilitySearchParams = NonNullable<operations["availability.search"]["requestBody"]>["content"]["application/json"];
59
+ /** Params for `calendar` on `availability` (GET /v1/availability/calendar). */
60
+ export type AvailabilityCalendarParams = NonNullable<operations["availability.calendar"]["parameters"]["query"]>;
61
+ /** Params for `list` on `blocks` (GET /v1/blocks). */
62
+ export type BlockListParams = WithMetadataFilter<NonNullable<operations["blocks.list"]["parameters"]["query"]>>;
63
+ /** Params for `create` on `blocks` (POST /v1/blocks). */
64
+ export type BlockCreateParams = NonNullable<operations["blocks.create"]["requestBody"]>["content"]["application/json"];
65
+ /** Params for `update` on `blocks` (POST /v1/blocks/{id}). */
66
+ export type BlockUpdateParams = NonNullable<operations["blocks.update"]["requestBody"]>["content"]["application/json"];
67
+ /** Params for `list` on `bookings` (GET /v1/bookings). */
68
+ export type BookingListParams = WithMetadataFilter<NonNullable<operations["bookings.list"]["parameters"]["query"]>>;
69
+ /** Params for `create` on `bookings` (POST /v1/bookings). */
70
+ export type BookingCreateParams = NonNullable<operations["bookings.create"]["requestBody"]>["content"]["application/json"];
71
+ /** Params for `import` on `bookings` (POST /v1/bookings/import). */
72
+ export type BookingImportParams = NonNullable<operations["bookings.importBookings"]["requestBody"]>["content"]["application/json"];
73
+ /** Params for `update` on `bookings` (POST /v1/bookings/{id}). */
74
+ export type BookingUpdateParams = NonNullable<operations["bookings.update"]["requestBody"]>["content"]["application/json"];
75
+ /** Params for `list` on `attendees` (GET /v1/bookings/{id}/attendees). */
76
+ export type AttendeeListParams = WithMetadataFilter<NonNullable<operations["attendees.listAttendees"]["parameters"]["query"]>>;
77
+ /** Params for `create` on `attendees` (POST /v1/bookings/{id}/attendees). */
78
+ export type AttendeeCreateParams = NonNullable<operations["attendees.createAttendee"]["requestBody"]>["content"]["application/json"];
79
+ /** Params for `cancel` on `bookings` (POST /v1/bookings/{id}/cancel). */
80
+ export type BookingCancelParams = NonNullable<operations["bookings.cancel"]["requestBody"]>["content"]["application/json"];
81
+ /** Params for `reschedule` on `bookings` (POST /v1/bookings/{id}/reschedule). */
82
+ export type BookingRescheduleParams = NonNullable<operations["bookings.reschedule"]["requestBody"]>["content"]["application/json"];
83
+ /** Params for `create` on `conflictPreviews` (POST /v1/conflict_previews). */
84
+ export type ConflictPreviewCreateParams = NonNullable<operations["conflict_previews.create"]["requestBody"]>["content"]["application/json"];
85
+ /** Params for `list` on `events` (GET /v1/events). */
86
+ export type EventListParams = NonNullable<operations["events.list"]["parameters"]["query"]>;
87
+ /** Params for `resend` on `events` (POST /v1/events/{id}/resend). */
88
+ export type EventResendParams = NonNullable<operations["events.resend"]["requestBody"]>["content"]["application/json"];
89
+ /** Params for `list` on `locations` (GET /v1/locations). */
90
+ export type LocationListParams = WithMetadataFilter<NonNullable<operations["locations.list"]["parameters"]["query"]>>;
91
+ /** Params for `create` on `locations` (POST /v1/locations). */
92
+ export type LocationCreateParams = NonNullable<operations["locations.create"]["requestBody"]>["content"]["application/json"];
93
+ /** Params for `update` on `locations` (POST /v1/locations/{id}). */
94
+ export type LocationUpdateParams = NonNullable<operations["locations.update"]["requestBody"]>["content"]["application/json"];
95
+ /** Params for `list` on `resources` (GET /v1/resources). */
96
+ export type ResourceListParams = WithMetadataFilter<NonNullable<operations["resources.list"]["parameters"]["query"]>>;
97
+ /** Params for `create` on `resources` (POST /v1/resources). */
98
+ export type ResourceCreateParams = NonNullable<operations["resources.create"]["requestBody"]>["content"]["application/json"];
99
+ /** Params for `update` on `resources` (POST /v1/resources/{id}). */
100
+ export type ResourceUpdateParams = NonNullable<operations["resources.update"]["requestBody"]>["content"]["application/json"];
101
+ /** Params for `list` on `scheduleOverrides` (GET /v1/schedule_overrides). */
102
+ export type ScheduleOverrideListParams = WithMetadataFilter<NonNullable<operations["schedule_overrides.listOverrides"]["parameters"]["query"]>>;
103
+ /** Params for `create` on `scheduleOverrides` (POST /v1/schedule_overrides). */
104
+ export type ScheduleOverrideCreateParams = NonNullable<operations["schedule_overrides.createOverride"]["requestBody"]>["content"]["application/json"];
105
+ /** Params for `update` on `scheduleOverrides` (POST /v1/schedule_overrides/{id}). */
106
+ export type ScheduleOverrideUpdateParams = NonNullable<operations["schedule_overrides.updateOverride"]["requestBody"]>["content"]["application/json"];
107
+ /** Params for `list` on `schedules` (GET /v1/schedules). */
108
+ export type ScheduleListParams = WithMetadataFilter<NonNullable<operations["schedules.list"]["parameters"]["query"]>>;
109
+ /** Params for `create` on `schedules` (POST /v1/schedules). */
110
+ export type ScheduleCreateParams = NonNullable<operations["schedules.create"]["requestBody"]>["content"]["application/json"];
111
+ /** Params for `update` on `schedules` (POST /v1/schedules/{id}). */
112
+ export type ScheduleUpdateParams = NonNullable<operations["schedules.update"]["requestBody"]>["content"]["application/json"];
113
+ /** Params for `list` on `series` (GET /v1/series). */
114
+ export type SeriesListParams = WithMetadataFilter<NonNullable<operations["series.list"]["parameters"]["query"]>>;
115
+ /** Params for `create` on `series` (POST /v1/series). */
116
+ export type SeriesCreateParams = NonNullable<operations["series.create"]["requestBody"]>["content"]["application/json"];
117
+ /** Params for `update` on `series` (POST /v1/series/{id}). */
118
+ export type SeriesUpdateParams = NonNullable<operations["series.update"]["requestBody"]>["content"]["application/json"];
119
+ /** Params for `cancel` on `series` (POST /v1/series/{id}/cancel). */
120
+ export type SeriesCancelParams = NonNullable<operations["series.cancel"]["requestBody"]>["content"]["application/json"];
121
+ /** Params for `split` on `series` (POST /v1/series/{id}/split). */
122
+ export type SeriesSplitParams = NonNullable<operations["series.split"]["requestBody"]>["content"]["application/json"];
123
+ /** Params for `get` on `usage` (GET /v1/usage). */
124
+ export type UsageGetParams = NonNullable<operations["usage.get"]["parameters"]["query"]>;
125
+ /** Params for `list` on `webhookEndpoints` (GET /v1/webhook_endpoints). */
126
+ export type WebhookEndpointListParams = WithMetadataFilter<NonNullable<operations["webhook_endpoints.list"]["parameters"]["query"]>>;
127
+ /** Params for `create` on `webhookEndpoints` (POST /v1/webhook_endpoints). */
128
+ export type WebhookEndpointCreateParams = NonNullable<operations["webhook_endpoints.create"]["requestBody"]>["content"]["application/json"];
129
+ /** Params for `update` on `webhookEndpoints` (POST /v1/webhook_endpoints/{id}). */
130
+ export type WebhookEndpointUpdateParams = NonNullable<operations["webhook_endpoints.update"]["requestBody"]>["content"]["application/json"];
131
+ /** Params for `deliveries` on `webhookEndpoints` (GET /v1/webhook_endpoints/{id}/deliveries). */
132
+ export type WebhookEndpointDeliveriesParams = NonNullable<operations["webhook_endpoints.deliveries"]["parameters"]["query"]>;
133
+ /** Params for `resend` on `webhookEndpoints` (POST /v1/webhook_endpoints/{id}/resend). */
134
+ export type WebhookEndpointResendParams = NonNullable<operations["webhook_endpoints.resend"]["requestBody"]>["content"]["application/json"];
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // Code generated by scripts/generate.mjs from openapi.json. DO NOT EDIT.
3
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,16 @@
1
+ export { Tiempo } from './client.js';
2
+ export { Tiempo as default } from './client.js';
3
+ export { DEFAULT_BASE_URL } from './core.js';
4
+ export type { TiempoConfig, RequestOptions } from './core.js';
5
+ export { ListPromise } from './list.js';
6
+ export type { ListPage, PageParams } from './list.js';
7
+ export { TiempoError, TiempoInvalidRequestError, TiempoAuthenticationError, TiempoPermissionError, TiempoConflictError, TiempoIdempotencyError, TiempoRateLimitError, TiempoAPIError, TiempoConnectionError, TiempoSignatureVerificationError, } from './errors.js';
8
+ export type { TiempoErrorBody } from './errors.js';
9
+ export { EVENT_TYPES, isKnownEventType } from './events.js';
10
+ export type { TiempoEvent, TiempoEventOf, TiempoEventType, EventObject, EventObjectMap } from './events.js';
11
+ export { constructEvent, generateTestHeader, Webhooks, SIGNATURE_HEADER } from './webhooks.js';
12
+ export type { ConstructEventOptions, GenerateTestHeaderOptions } from './webhooks.js';
13
+ export { API_VERSION, SDK_VERSION } from './generated/meta.js';
14
+ export type { WithMetadataFilter } from './shared.js';
15
+ export * from './generated/types.js';
16
+ export * from './generated/resources.js';
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.SDK_VERSION = exports.API_VERSION = exports.SIGNATURE_HEADER = exports.Webhooks = exports.generateTestHeader = exports.constructEvent = exports.isKnownEventType = exports.EVENT_TYPES = exports.TiempoSignatureVerificationError = exports.TiempoConnectionError = exports.TiempoAPIError = exports.TiempoRateLimitError = exports.TiempoIdempotencyError = exports.TiempoConflictError = exports.TiempoPermissionError = exports.TiempoAuthenticationError = exports.TiempoInvalidRequestError = exports.TiempoError = exports.ListPromise = exports.DEFAULT_BASE_URL = exports.default = exports.Tiempo = void 0;
18
+ var client_js_1 = require("./client.js");
19
+ Object.defineProperty(exports, "Tiempo", { enumerable: true, get: function () { return client_js_1.Tiempo; } });
20
+ var client_js_2 = require("./client.js");
21
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return client_js_2.Tiempo; } });
22
+ var core_js_1 = require("./core.js");
23
+ Object.defineProperty(exports, "DEFAULT_BASE_URL", { enumerable: true, get: function () { return core_js_1.DEFAULT_BASE_URL; } });
24
+ var list_js_1 = require("./list.js");
25
+ Object.defineProperty(exports, "ListPromise", { enumerable: true, get: function () { return list_js_1.ListPromise; } });
26
+ var errors_js_1 = require("./errors.js");
27
+ Object.defineProperty(exports, "TiempoError", { enumerable: true, get: function () { return errors_js_1.TiempoError; } });
28
+ Object.defineProperty(exports, "TiempoInvalidRequestError", { enumerable: true, get: function () { return errors_js_1.TiempoInvalidRequestError; } });
29
+ Object.defineProperty(exports, "TiempoAuthenticationError", { enumerable: true, get: function () { return errors_js_1.TiempoAuthenticationError; } });
30
+ Object.defineProperty(exports, "TiempoPermissionError", { enumerable: true, get: function () { return errors_js_1.TiempoPermissionError; } });
31
+ Object.defineProperty(exports, "TiempoConflictError", { enumerable: true, get: function () { return errors_js_1.TiempoConflictError; } });
32
+ Object.defineProperty(exports, "TiempoIdempotencyError", { enumerable: true, get: function () { return errors_js_1.TiempoIdempotencyError; } });
33
+ Object.defineProperty(exports, "TiempoRateLimitError", { enumerable: true, get: function () { return errors_js_1.TiempoRateLimitError; } });
34
+ Object.defineProperty(exports, "TiempoAPIError", { enumerable: true, get: function () { return errors_js_1.TiempoAPIError; } });
35
+ Object.defineProperty(exports, "TiempoConnectionError", { enumerable: true, get: function () { return errors_js_1.TiempoConnectionError; } });
36
+ Object.defineProperty(exports, "TiempoSignatureVerificationError", { enumerable: true, get: function () { return errors_js_1.TiempoSignatureVerificationError; } });
37
+ var events_js_1 = require("./events.js");
38
+ Object.defineProperty(exports, "EVENT_TYPES", { enumerable: true, get: function () { return events_js_1.EVENT_TYPES; } });
39
+ Object.defineProperty(exports, "isKnownEventType", { enumerable: true, get: function () { return events_js_1.isKnownEventType; } });
40
+ var webhooks_js_1 = require("./webhooks.js");
41
+ Object.defineProperty(exports, "constructEvent", { enumerable: true, get: function () { return webhooks_js_1.constructEvent; } });
42
+ Object.defineProperty(exports, "generateTestHeader", { enumerable: true, get: function () { return webhooks_js_1.generateTestHeader; } });
43
+ Object.defineProperty(exports, "Webhooks", { enumerable: true, get: function () { return webhooks_js_1.Webhooks; } });
44
+ Object.defineProperty(exports, "SIGNATURE_HEADER", { enumerable: true, get: function () { return webhooks_js_1.SIGNATURE_HEADER; } });
45
+ var meta_js_1 = require("./generated/meta.js");
46
+ Object.defineProperty(exports, "API_VERSION", { enumerable: true, get: function () { return meta_js_1.API_VERSION; } });
47
+ Object.defineProperty(exports, "SDK_VERSION", { enumerable: true, get: function () { return meta_js_1.SDK_VERSION; } });
48
+ __exportStar(require("./generated/types.js"), exports);
49
+ __exportStar(require("./generated/resources.js"), exports);
@@ -0,0 +1,43 @@
1
+ /** One page of a list endpoint. */
2
+ export interface ListPage<T> {
3
+ object: 'list';
4
+ data: T[];
5
+ has_more: boolean;
6
+ }
7
+ /** Query params every paginating list accepts. */
8
+ export interface PageParams {
9
+ limit?: number;
10
+ starting_after?: string;
11
+ ending_before?: string;
12
+ [key: string]: unknown;
13
+ }
14
+ type FetchPage<T> = (params: PageParams) => Promise<ListPage<T>>;
15
+ /**
16
+ * What a list method returns. `await` it for one page; `for await` over it to
17
+ * walk every item across pages.
18
+ *
19
+ * Iteration moves forward with `starting_after` (the last item's id). If you
20
+ * passed `ending_before`, it moves backwards with `ending_before` (the first
21
+ * item's id) and yields each page's items last to first, so you walk away from
22
+ * your cursor.
23
+ *
24
+ * The first page is fetched once, on first use, and shared between `await` and
25
+ * iteration.
26
+ */
27
+ export declare class ListPromise<T> implements PromiseLike<ListPage<T>>, AsyncIterable<T> {
28
+ private readonly fetchPage;
29
+ private readonly params;
30
+ private readonly paginates;
31
+ private first;
32
+ constructor(fetchPage: FetchPage<T>, params: PageParams, paginates?: boolean);
33
+ private firstPage;
34
+ then<R1 = ListPage<T>, R2 = never>(onfulfilled?: ((value: ListPage<T>) => R1 | PromiseLike<R1>) | null, onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null): Promise<R1 | R2>;
35
+ catch<R = never>(onrejected?: ((reason: unknown) => R | PromiseLike<R>) | null): Promise<ListPage<T> | R>;
36
+ finally(onfinally?: (() => void) | null): Promise<ListPage<T>>;
37
+ [Symbol.asyncIterator](): AsyncIterator<T>;
38
+ /** Collects items into an array, stopping after `limit` (required, to avoid surprises). */
39
+ toArray({ limit }: {
40
+ limit: number;
41
+ }): Promise<T[]>;
42
+ }
43
+ export {};
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ListPromise = void 0;
4
+ function idOf(item) {
5
+ const id = item && typeof item === 'object' ? item.id : undefined;
6
+ if (typeof id !== 'string')
7
+ throw new TypeError('Cannot paginate: list item has no string `id`');
8
+ return id;
9
+ }
10
+ /**
11
+ * What a list method returns. `await` it for one page; `for await` over it to
12
+ * walk every item across pages.
13
+ *
14
+ * Iteration moves forward with `starting_after` (the last item's id). If you
15
+ * passed `ending_before`, it moves backwards with `ending_before` (the first
16
+ * item's id) and yields each page's items last to first, so you walk away from
17
+ * your cursor.
18
+ *
19
+ * The first page is fetched once, on first use, and shared between `await` and
20
+ * iteration.
21
+ */
22
+ class ListPromise {
23
+ fetchPage;
24
+ params;
25
+ paginates;
26
+ first;
27
+ constructor(fetchPage, params, paginates = true) {
28
+ this.fetchPage = fetchPage;
29
+ this.params = params;
30
+ this.paginates = paginates;
31
+ }
32
+ firstPage() {
33
+ this.first ??= this.fetchPage(this.params);
34
+ return this.first;
35
+ }
36
+ then(onfulfilled, onrejected) {
37
+ return this.firstPage().then(onfulfilled, onrejected);
38
+ }
39
+ catch(onrejected) {
40
+ return this.firstPage().catch(onrejected);
41
+ }
42
+ finally(onfinally) {
43
+ return this.firstPage().finally(onfinally);
44
+ }
45
+ async *[Symbol.asyncIterator]() {
46
+ const backwards = this.params.ending_before !== undefined && this.params.starting_after === undefined;
47
+ let page = await this.firstPage();
48
+ for (;;) {
49
+ const items = backwards ? [...page.data].reverse() : page.data;
50
+ for (const item of items)
51
+ yield item;
52
+ if (!this.paginates || !page.has_more || page.data.length === 0)
53
+ return;
54
+ const next = { ...this.params };
55
+ if (backwards) {
56
+ next.ending_before = idOf(page.data[0]);
57
+ }
58
+ else {
59
+ delete next.ending_before;
60
+ next.starting_after = idOf(page.data[page.data.length - 1]);
61
+ }
62
+ page = await this.fetchPage(next);
63
+ }
64
+ }
65
+ /** Collects items into an array, stopping after `limit` (required, to avoid surprises). */
66
+ async toArray({ limit }) {
67
+ const out = [];
68
+ if (limit <= 0)
69
+ return out;
70
+ for await (const item of this) {
71
+ out.push(item);
72
+ if (out.length >= limit)
73
+ break;
74
+ }
75
+ return out;
76
+ }
77
+ }
78
+ exports.ListPromise = ListPromise;
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,8 @@
1
+ /** Encodes a path segment. */
2
+ export declare function encodePath(value: string): string;
3
+ /**
4
+ * Encodes a query object: undefined and null are skipped, booleans become
5
+ * `true`/`false`, arrays repeat the key, and objects (like `metadata`) become
6
+ * `key[sub]=value`.
7
+ */
8
+ export declare function encodeQuery(query: object | undefined): string;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encodePath = encodePath;
4
+ exports.encodeQuery = encodeQuery;
5
+ /** Encodes a path segment. */
6
+ function encodePath(value) {
7
+ if (typeof value !== 'string' || value === '') {
8
+ throw new TypeError(`Expected a non-empty id string, got ${JSON.stringify(value)}`);
9
+ }
10
+ return encodeURIComponent(value);
11
+ }
12
+ function scalar(value) {
13
+ if (value instanceof Date)
14
+ return value.toISOString();
15
+ if (typeof value === 'boolean')
16
+ return value ? 'true' : 'false';
17
+ return String(value);
18
+ }
19
+ function add(out, key, value) {
20
+ if (value === undefined || value === null)
21
+ return;
22
+ if (Array.isArray(value)) {
23
+ for (const v of value)
24
+ add(out, key, v);
25
+ return;
26
+ }
27
+ if (typeof value === 'object' && !(value instanceof Date)) {
28
+ for (const [k, v] of Object.entries(value))
29
+ add(out, `${key}[${k}]`, v);
30
+ return;
31
+ }
32
+ out.append(key, scalar(value));
33
+ }
34
+ /**
35
+ * Encodes a query object: undefined and null are skipped, booleans become
36
+ * `true`/`false`, arrays repeat the key, and objects (like `metadata`) become
37
+ * `key[sub]=value`.
38
+ */
39
+ function encodeQuery(query) {
40
+ if (!query)
41
+ return '';
42
+ const out = new URLSearchParams();
43
+ for (const [k, v] of Object.entries(query))
44
+ add(out, k, v);
45
+ const s = out.toString();
46
+ return s ? `?${s}` : '';
47
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Replaces the spec's single `metadata[key]` query param with a map. Each entry
3
+ * is sent as `metadata[k]=v`; several entries must all match.
4
+ */
5
+ export type WithMetadataFilter<Q> = Omit<Q, 'metadata[key]'> & {
6
+ metadata?: Record<string, string>;
7
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,34 @@
1
+ import type { TiempoEvent } from './events.js';
2
+ /** The header Tiempo signs webhook deliveries with. */
3
+ export declare const SIGNATURE_HEADER = "Tiempo-Signature";
4
+ export interface ConstructEventOptions {
5
+ /** Maximum age (and clock skew) of the signature timestamp, in seconds. Default 300. */
6
+ tolerance?: number;
7
+ /** The current time, as a `Date` or unix seconds. Default: now. */
8
+ now?: Date | number;
9
+ }
10
+ export interface GenerateTestHeaderOptions {
11
+ /** The exact body you will pass to `constructEvent`. */
12
+ payload: string | Uint8Array;
13
+ /** The endpoint's `tpw_…` secret. */
14
+ secret: string;
15
+ /** Unix seconds. Default: now. */
16
+ timestamp?: number;
17
+ }
18
+ /**
19
+ * Verifies a webhook delivery and returns its event.
20
+ *
21
+ * Pass the raw request body exactly as received (not re-serialised JSON), the
22
+ * `Tiempo-Signature` header, and the endpoint's `tpw_…` secret. Throws
23
+ * {@link TiempoSignatureVerificationError} if the signature doesn't match or
24
+ * the timestamp is outside `tolerance`.
25
+ */
26
+ export declare function constructEvent(payload: string | Uint8Array, signatureHeader: string | null | undefined, secret: string, options?: ConstructEventOptions): Promise<TiempoEvent>;
27
+ /** Builds a valid `Tiempo-Signature` header for a payload, for your own tests. */
28
+ export declare function generateTestHeader({ payload, secret, timestamp }: GenerateTestHeaderOptions): Promise<string>;
29
+ /** `tiempo.webhooks`: the same functions, on the client. */
30
+ export declare class Webhooks {
31
+ readonly constructEvent: typeof constructEvent;
32
+ readonly generateTestHeader: typeof generateTestHeader;
33
+ readonly signatureHeader = "Tiempo-Signature";
34
+ }
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Webhooks = exports.SIGNATURE_HEADER = void 0;
4
+ exports.constructEvent = constructEvent;
5
+ exports.generateTestHeader = generateTestHeader;
6
+ const crypto_js_1 = require("./crypto.js");
7
+ const errors_js_1 = require("./errors.js");
8
+ /** The header Tiempo signs webhook deliveries with. */
9
+ exports.SIGNATURE_HEADER = 'Tiempo-Signature';
10
+ const encoder = new TextEncoder();
11
+ function fail(message) {
12
+ throw new errors_js_1.TiempoSignatureVerificationError({ message });
13
+ }
14
+ function bytesOf(payload) {
15
+ return typeof payload === 'string' ? encoder.encode(payload) : payload;
16
+ }
17
+ function hex(buf) {
18
+ return Array.from(new Uint8Array(buf), (b) => b.toString(16).padStart(2, '0')).join('');
19
+ }
20
+ /** Constant-time string comparison (for equal-length hex digests). */
21
+ function timingSafeEqual(a, b) {
22
+ if (a.length !== b.length)
23
+ return false;
24
+ let diff = 0;
25
+ for (let i = 0; i < a.length; i++)
26
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
27
+ return diff === 0;
28
+ }
29
+ async function sign(secret, timestamp, payload) {
30
+ const { subtle } = await (0, crypto_js_1.webCrypto)();
31
+ const key = await subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
32
+ const prefix = encoder.encode(`${timestamp}.`);
33
+ const message = new Uint8Array(prefix.length + payload.length);
34
+ message.set(prefix, 0);
35
+ message.set(payload, prefix.length);
36
+ return hex(await subtle.sign('HMAC', key, message));
37
+ }
38
+ function parseHeader(header) {
39
+ let timestamp;
40
+ const signatures = [];
41
+ for (const part of header.split(',')) {
42
+ const eq = part.indexOf('=');
43
+ if (eq < 0)
44
+ continue;
45
+ const key = part.slice(0, eq).trim();
46
+ const value = part.slice(eq + 1).trim();
47
+ if (key === 't' && /^\d+$/.test(value))
48
+ timestamp = Number(value);
49
+ else if (key === 'v1' && value)
50
+ signatures.push(value.toLowerCase());
51
+ }
52
+ if (timestamp === undefined)
53
+ fail('Tiempo-Signature header has no timestamp (t=…)');
54
+ if (signatures.length === 0)
55
+ fail('Tiempo-Signature header has no v1 signature');
56
+ return { timestamp, signatures };
57
+ }
58
+ /**
59
+ * Verifies a webhook delivery and returns its event.
60
+ *
61
+ * Pass the raw request body exactly as received (not re-serialised JSON), the
62
+ * `Tiempo-Signature` header, and the endpoint's `tpw_…` secret. Throws
63
+ * {@link TiempoSignatureVerificationError} if the signature doesn't match or
64
+ * the timestamp is outside `tolerance`.
65
+ */
66
+ async function constructEvent(payload, signatureHeader, secret, options = {}) {
67
+ if (typeof payload !== 'string' && !(payload instanceof Uint8Array)) {
68
+ fail('Webhook payload must be the raw body as a string or bytes, not a parsed object (use express.raw()).');
69
+ }
70
+ if (typeof signatureHeader !== 'string' || signatureHeader === '')
71
+ fail('Missing Tiempo-Signature header');
72
+ if (typeof secret !== 'string' || secret === '')
73
+ fail('Missing webhook signing secret (tpw_…)');
74
+ const tolerance = options.tolerance ?? 300;
75
+ const nowSeconds = options.now instanceof Date
76
+ ? Math.floor(options.now.getTime() / 1000)
77
+ : options.now ?? Math.floor(Date.now() / 1000);
78
+ const { timestamp, signatures } = parseHeader(signatureHeader);
79
+ const bytes = bytesOf(payload);
80
+ const expected = await sign(secret, timestamp, bytes);
81
+ let matched = false;
82
+ for (const candidate of signatures) {
83
+ if (timingSafeEqual(candidate, expected))
84
+ matched = true;
85
+ }
86
+ if (!matched)
87
+ fail('No v1 signature in Tiempo-Signature matches the payload. Check the secret and that the body is unmodified.');
88
+ if (Math.abs(nowSeconds - timestamp) > tolerance) {
89
+ fail(`Tiempo-Signature timestamp ${timestamp} is outside the ${tolerance}s tolerance`);
90
+ }
91
+ const text = typeof payload === 'string' ? payload : new TextDecoder().decode(payload);
92
+ let event;
93
+ try {
94
+ event = JSON.parse(text);
95
+ }
96
+ catch {
97
+ fail('Webhook payload is not valid JSON');
98
+ }
99
+ if (!event || typeof event !== 'object' || event.object !== 'event') {
100
+ fail('Webhook payload is not a Tiempo event');
101
+ }
102
+ return event;
103
+ }
104
+ /** Builds a valid `Tiempo-Signature` header for a payload, for your own tests. */
105
+ async function generateTestHeader({ payload, secret, timestamp }) {
106
+ const t = timestamp ?? Math.floor(Date.now() / 1000);
107
+ return `t=${t},v1=${await sign(secret, t, bytesOf(payload))}`;
108
+ }
109
+ /** `tiempo.webhooks`: the same functions, on the client. */
110
+ class Webhooks {
111
+ constructEvent = constructEvent;
112
+ generateTestHeader = generateTestHeader;
113
+ signatureHeader = exports.SIGNATURE_HEADER;
114
+ }
115
+ exports.Webhooks = Webhooks;
@@ -0,0 +1,24 @@
1
+ import { type TiempoConfig } from './core.js';
2
+ import { TiempoResources } from './generated/resources.js';
3
+ import { Webhooks } from './webhooks.js';
4
+ /**
5
+ * The Tiempo API client.
6
+ *
7
+ * ```ts
8
+ * const tiempo = new Tiempo(process.env.TIEMPO_API_KEY!); // https://api.tiempo.one unless you give a baseUrl
9
+ * const business = tiempo.withAccount('acct_…');
10
+ * const booking = await business.bookings.create({ segments: [...] });
11
+ * ```
12
+ */
13
+ export declare class Tiempo extends TiempoResources {
14
+ /** Webhook signature verification. */
15
+ readonly webhooks: Webhooks;
16
+ private readonly core;
17
+ constructor(apiKey: string, config?: TiempoConfig);
18
+ /** A client that acts for one business (`acct_…`), sharing this one's key and settings. */
19
+ withAccount(account: string): Tiempo;
20
+ /** The business this client acts for, if any. */
21
+ get account(): string | undefined;
22
+ /** The `Tiempo-Version` this client sends. */
23
+ get apiVersion(): string;
24
+ }
@@ -0,0 +1,38 @@
1
+ import { HttpClient } from './core.js';
2
+ import { TiempoResources } from './generated/resources.js';
3
+ import { Webhooks } from './webhooks.js';
4
+ /**
5
+ * The Tiempo API client.
6
+ *
7
+ * ```ts
8
+ * const tiempo = new Tiempo(process.env.TIEMPO_API_KEY!); // https://api.tiempo.one unless you give a baseUrl
9
+ * const business = tiempo.withAccount('acct_…');
10
+ * const booking = await business.bookings.create({ segments: [...] });
11
+ * ```
12
+ */
13
+ export class Tiempo extends TiempoResources {
14
+ /** Webhook signature verification. */
15
+ webhooks;
16
+ core;
17
+ constructor(apiKey, config, resolved) {
18
+ const core = new HttpClient(resolved ?? HttpClient.resolve(apiKey, config));
19
+ super(core);
20
+ this.core = core;
21
+ this.webhooks = new Webhooks();
22
+ }
23
+ /** A client that acts for one business (`acct_…`), sharing this one's key and settings. */
24
+ withAccount(account) {
25
+ if (typeof account !== 'string' || !account)
26
+ throw new TypeError('Tiempo: withAccount needs an account id (acct_…)');
27
+ const cfg = this.core.config;
28
+ return new Tiempo(cfg.apiKey, { baseUrl: cfg.baseUrl }, { ...cfg, account });
29
+ }
30
+ /** The business this client acts for, if any. */
31
+ get account() {
32
+ return this.core.config.account;
33
+ }
34
+ /** The `Tiempo-Version` this client sends. */
35
+ get apiVersion() {
36
+ return this.core.config.apiVersion;
37
+ }
38
+ }