@seamapi/http 2.18.0 → 2.19.0

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.
@@ -1,9 +1,22 @@
1
1
  import type { ResolveActionAttemptOptions } from './resolve-action-attempt.js'
2
2
 
3
+ /**
4
+ * Options for how a {@link SeamHttpRequest} is executed.
5
+ */
3
6
  export interface SeamHttpRequestOptions {
7
+ /**
8
+ * Controls whether to wait for the action attempt to resolve
9
+ * when a request returns an action attempt.
10
+ * Pass a boolean to toggle waiting,
11
+ * or {@link ResolveActionAttemptOptions} to also configure
12
+ * the timeout and polling interval.
13
+ */
4
14
  waitForActionAttempt?: boolean | ResolveActionAttemptOptions
5
15
  }
6
16
 
17
+ /**
18
+ * Returns true if the key is the name of a {@link SeamHttpRequestOptions} property.
19
+ */
7
20
  export const isSeamHttpRequestOption = (
8
21
  key: string,
9
22
  ): key is keyof SeamHttpRequestOptions => {
@@ -1,14 +1,35 @@
1
1
  import type { ActionAttempt } from './resources/action-attempt.js'
2
2
 
3
+ /**
4
+ * Client used to poll action attempts by id, e.g., `SeamHttpActionAttempts`.
5
+ */
3
6
  export interface ActionAttemptsClient {
4
7
  get(parameters: { action_attempt_id: string }): PromiseLike<ActionAttempt>
5
8
  }
6
9
 
10
+ /**
11
+ * Options for waiting until an action attempt resolves.
12
+ */
7
13
  export interface ResolveActionAttemptOptions {
14
+ /**
15
+ * Maximum time in milliseconds to wait for the action attempt to resolve.
16
+ */
8
17
  timeout?: number
18
+
19
+ /**
20
+ * Time in milliseconds to wait between polls of the action attempt.
21
+ */
9
22
  pollingInterval?: number
10
23
  }
11
24
 
25
+ /**
26
+ * Polls a pending action attempt until it succeeds, fails, or times out.
27
+ *
28
+ * @returns The succeeded action attempt.
29
+ * @throws {@link SeamActionAttemptFailedError} if the action attempt fails.
30
+ * @throws {@link SeamActionAttemptTimeoutError} if the action attempt
31
+ * does not resolve within the timeout.
32
+ */
12
33
  export const resolveActionAttempt = async <T extends ActionAttempt>(
13
34
  actionAttempt: T,
14
35
  actionAttempts: ActionAttemptsClient,
@@ -59,12 +80,18 @@ const pollActionAttempt = async <T extends ActionAttempt>(
59
80
  )
60
81
  }
61
82
 
83
+ /**
84
+ * Returns true if the error is a {@link SeamActionAttemptError}.
85
+ */
62
86
  export const isSeamActionAttemptError = <T extends ActionAttempt>(
63
87
  error: unknown,
64
88
  ): error is SeamActionAttemptError<T> => {
65
89
  return error instanceof SeamActionAttemptError
66
90
  }
67
91
 
92
+ /**
93
+ * Error relating to an action attempt.
94
+ */
68
95
  export class SeamActionAttemptError<T extends ActionAttempt> extends Error {
69
96
  actionAttempt: T
70
97
 
@@ -75,15 +102,24 @@ export class SeamActionAttemptError<T extends ActionAttempt> extends Error {
75
102
  }
76
103
  }
77
104
 
105
+ /**
106
+ * Returns true if the error is a {@link SeamActionAttemptFailedError}.
107
+ */
78
108
  export const isSeamActionAttemptFailedError = <T extends ActionAttempt>(
79
109
  error: unknown,
80
110
  ): error is SeamActionAttemptFailedError<T> => {
81
111
  return error instanceof SeamActionAttemptFailedError
82
112
  }
83
113
 
114
+ /**
115
+ * Error thrown when an action attempt fails.
116
+ */
84
117
  export class SeamActionAttemptFailedError<
85
118
  T extends ActionAttempt,
86
119
  > extends SeamActionAttemptError<T> {
120
+ /**
121
+ * Error type returned by the Seam API for the failed action attempt.
122
+ */
87
123
  code: string
88
124
 
89
125
  constructor(actionAttempt: FailedActionAttempt<T>) {
@@ -93,12 +129,18 @@ export class SeamActionAttemptFailedError<
93
129
  }
94
130
  }
95
131
 
132
+ /**
133
+ * Returns true if the error is a {@link SeamActionAttemptTimeoutError}.
134
+ */
96
135
  export const isSeamActionAttemptTimeoutError = <T extends ActionAttempt>(
97
136
  error: unknown,
98
137
  ): error is SeamActionAttemptTimeoutError<T> => {
99
138
  return error instanceof SeamActionAttemptTimeoutError
100
139
  }
101
140
 
141
+ /**
142
+ * Error thrown when an action attempt does not resolve within the timeout.
143
+ */
102
144
  export class SeamActionAttemptTimeoutError<
103
145
  T extends ActionAttempt,
104
146
  > extends SeamActionAttemptError<T> {
@@ -120,10 +162,16 @@ const isFailedActionAttempt = <T extends ActionAttempt>(
120
162
  actionAttempt: T,
121
163
  ): actionAttempt is FailedActionAttempt<T> => actionAttempt.status === 'error'
122
164
 
165
+ /**
166
+ * An action attempt that has succeeded.
167
+ */
123
168
  export type SucceededActionAttempt<T extends ActionAttempt> = T & {
124
169
  status: 'success'
125
170
  }
126
171
 
172
+ /**
173
+ * An action attempt that has failed.
174
+ */
127
175
  export type FailedActionAttempt<T extends ActionAttempt> = T & {
128
176
  status: 'error'
129
177
  }
@@ -1716,18 +1716,6 @@ export type Device = {
1716
1716
  * Set to true when the device does not support the /dual-setpoints API endpoint.
1717
1717
  */
1718
1718
  dual_setpoints_not_supported?: boolean | undefined
1719
- /**
1720
- * Enforced cooling setpoint range in Celsius for a Sensi device, derived from an OutOfRange API error.
1721
- */
1722
- enforced_cooling_setpoint_range_celsius?: Array<number> | undefined
1723
- /**
1724
- * Enforced heating setpoint range in Celsius for a Sensi device, derived from an OutOfRange API error.
1725
- */
1726
- enforced_heating_setpoint_range_celsius?: Array<number> | undefined
1727
- /**
1728
- * Legacy combined enforced setpoint range in Celsius for a Sensi device, derived from an OutOfRange API error. Read as a fallback for the per-mode ranges below; no longer written.
1729
- */
1730
- enforced_setpoint_range_celsius?: Array<number> | undefined
1731
1719
  /**
1732
1720
  * Product type for a Sensi device.
1733
1721
  */
@@ -1,9 +1,25 @@
1
1
  import type { ApiError } from './api-error-types.js'
2
2
 
3
+ /**
4
+ * Error thrown when the Seam API returns an error response.
5
+ */
3
6
  export class SeamHttpApiError extends Error {
7
+ /**
8
+ * Error type returned by the Seam API, e.g., `invalid_input`.
9
+ */
4
10
  code: string
11
+
5
12
  statusCode: number
13
+
14
+ /**
15
+ * Unique identifier of the request that failed.
16
+ * Provide this to Seam support when reporting an issue.
17
+ */
6
18
  requestId: string
19
+
20
+ /**
21
+ * Additional error-specific data returned by the Seam API, if any.
22
+ */
7
23
  data?: unknown
8
24
 
9
25
  constructor(error: ApiError, statusCode: number, requestId: string) {
@@ -17,12 +33,18 @@ export class SeamHttpApiError extends Error {
17
33
  }
18
34
  }
19
35
 
36
+ /**
37
+ * Returns true if the error is a {@link SeamHttpApiError}.
38
+ */
20
39
  export const isSeamHttpApiError = (
21
40
  error: unknown,
22
41
  ): error is SeamHttpApiError => {
23
42
  return error instanceof SeamHttpApiError
24
43
  }
25
44
 
45
+ /**
46
+ * Error thrown when the Seam API returns a 401 Unauthorized error response.
47
+ */
26
48
  export class SeamHttpUnauthorizedError extends SeamHttpApiError {
27
49
  override code: 'unauthorized'
28
50
  override statusCode: 401
@@ -38,14 +60,21 @@ export class SeamHttpUnauthorizedError extends SeamHttpApiError {
38
60
  }
39
61
  }
40
62
 
63
+ /**
64
+ * Returns true if the error is a {@link SeamHttpUnauthorizedError}.
65
+ */
41
66
  export const isSeamHttpUnauthorizedError = (
42
67
  error: unknown,
43
68
  ): error is SeamHttpUnauthorizedError => {
44
69
  return error instanceof SeamHttpUnauthorizedError
45
70
  }
46
71
 
72
+ /**
73
+ * Error thrown when the Seam API returns an `invalid_input` error response.
74
+ */
47
75
  export class SeamHttpInvalidInputError extends SeamHttpApiError {
48
76
  override code: 'invalid_input'
77
+
49
78
  readonly #validationErrors: NonNullable<ApiError['validation_errors']>
50
79
 
51
80
  constructor(error: ApiError, statusCode: number, requestId: string) {
@@ -55,11 +84,20 @@ export class SeamHttpInvalidInputError extends SeamHttpApiError {
55
84
  this.#validationErrors = error.validation_errors ?? {}
56
85
  }
57
86
 
87
+ /**
88
+ * Returns the validation error messages for the request parameter,
89
+ * or an empty array if the parameter had no validation errors.
90
+ *
91
+ * @param paramName - Name of the request parameter.
92
+ */
58
93
  getValidationErrorMessages(paramName: string): string[] {
59
94
  return this.#validationErrors[paramName]?._errors ?? []
60
95
  }
61
96
  }
62
97
 
98
+ /**
99
+ * Returns true if the error is a {@link SeamHttpInvalidInputError}.
100
+ */
63
101
  export const isSeamHttpInvalidInputError = (
64
102
  error: unknown,
65
103
  ): error is SeamHttpInvalidInputError => {
@@ -29,6 +29,20 @@ interface SeamHttpRequestConfig<TResponseKey> {
29
29
  readonly requiredParameterNames?: readonly string[]
30
30
  }
31
31
 
32
+ /**
33
+ * A lazy request to the Seam API.
34
+ *
35
+ * Creating a SeamHttpRequest does not send anything over the network.
36
+ * The request is sent once `execute` is called,
37
+ * or when the request is awaited like a Promise,
38
+ * e.g., with `await`, `then`, `catch`, or `finally`.
39
+ * When the response contains an action attempt,
40
+ * awaiting the request also waits for the action attempt to resolve
41
+ * according to the `waitForActionAttempt` option.
42
+ *
43
+ * Before sending, the request may be inspected
44
+ * with `url`, `pathname`, `method`, `params`, and `body`.
45
+ */
32
46
  export class SeamHttpRequest<
33
47
  const TResponse,
34
48
  const TResponseKey extends keyof TResponse | undefined,
@@ -48,6 +62,10 @@ export class SeamHttpRequest<
48
62
  this.#config = config
49
63
  }
50
64
 
65
+ /**
66
+ * The key of the API response object containing the response data,
67
+ * or undefined if the endpoint returns an empty response.
68
+ */
51
69
  public get responseKey(): TResponseKey {
52
70
  return this.#config.responseKey
53
71
  }
@@ -56,6 +74,9 @@ export class SeamHttpRequest<
56
74
  return this.#config.hasPagination ?? false
57
75
  }
58
76
 
77
+ /**
78
+ * The full request URL including any serialized query parameters.
79
+ */
59
80
  public get url(): URL {
60
81
  const { client } = this.#parent
61
82
 
@@ -92,6 +113,12 @@ export class SeamHttpRequest<
92
113
  return this.#config.body
93
114
  }
94
115
 
116
+ /**
117
+ * Sends the request and returns the response data.
118
+ * If the response contains an action attempt,
119
+ * waits for the action attempt to resolve
120
+ * according to the `waitForActionAttempt` option.
121
+ */
95
122
  async execute(): Promise<
96
123
  TResponseKey extends keyof TResponse ? TResponse[TResponseKey] : undefined
97
124
  > {
@@ -130,6 +157,10 @@ export class SeamHttpRequest<
130
157
  return data
131
158
  }
132
159
 
160
+ /**
161
+ * Sends the request and returns the entire response body
162
+ * without waiting for any action attempt to resolve.
163
+ */
133
164
  async fetchResponse(): Promise<TResponse> {
134
165
  assertValidRequestParameters(
135
166
  this.#config.parameters,
@@ -9,6 +9,9 @@ interface SeamPaginatorParent {
9
9
 
10
10
  declare const $brand: unique symbol
11
11
 
12
+ /**
13
+ * Opaque cursor identifying a page of results returned by the Seam API.
14
+ */
12
15
  export type SeamPageCursor = string & { [$brand]: 'SeamPageCursor' }
13
16
 
14
17
  interface Pagination {
@@ -17,6 +20,15 @@ interface Pagination {
17
20
  readonly nextPageUrl: string | null
18
21
  }
19
22
 
23
+ /**
24
+ * Iterates over paginated results from Seam API list endpoints.
25
+ *
26
+ * Create a SeamPaginator with the client's `createPaginator` method.
27
+ * Fetch pages manually with `firstPage` and `nextPage`,
28
+ * iterate over pages with `for await`,
29
+ * iterate over items across all pages with `flatten`,
30
+ * or collect every item into a single array with `flattenToArray`.
31
+ */
20
32
  export class SeamPaginator<
21
33
  const TResponse,
22
34
  const TResponseKey extends keyof TResponse,
@@ -37,12 +49,19 @@ export class SeamPaginator<
37
49
  this.#request = request
38
50
  }
39
51
 
52
+ /**
53
+ * Fetches the first page of results along with the pagination state.
54
+ */
40
55
  async firstPage(): Promise<
41
56
  [EnsureReadonlyArray<TResponse[TResponseKey]>, Pagination]
42
57
  > {
43
58
  return await this.#fetch()
44
59
  }
45
60
 
61
+ /**
62
+ * Fetches the next page of results
63
+ * using the nextPageCursor returned with a previous page.
64
+ */
46
65
  async nextPage(
47
66
  nextPageCursor: Pagination['nextPageCursor'],
48
67
  ): Promise<[EnsureReadonlyArray<TResponse[TResponseKey]>, Pagination]> {
@@ -104,6 +123,9 @@ export class SeamPaginator<
104
123
  ] as const
105
124
  }
106
125
 
126
+ /**
127
+ * Fetches every page and returns all items in a single array.
128
+ */
107
129
  async flattenToArray(): Promise<
108
130
  EnsureReadonlyArray<TResponse[TResponseKey]>
109
131
  > {
@@ -117,6 +139,9 @@ export class SeamPaginator<
117
139
  return items as EnsureReadonlyArray<TResponse[TResponseKey]>
118
140
  }
119
141
 
142
+ /**
143
+ * Yields each item across all pages, fetching the next page as needed.
144
+ */
120
145
  async *flatten(): AsyncGenerator<
121
146
  EnsureReadonlyArray<TResponse[TResponseKey]>
122
147
  > {
@@ -132,6 +157,9 @@ export class SeamPaginator<
132
157
  }
133
158
  }
134
159
 
160
+ /**
161
+ * Yields each page of items, fetching the next page as needed.
162
+ */
135
163
  async *[Symbol.asyncIterator](): AsyncGenerator<
136
164
  EnsureReadonlyArray<TResponse[TResponseKey]>
137
165
  > {
@@ -1,3 +1,3 @@
1
- const seamapiJavascriptHttpVersion = '2.18.0'
1
+ const seamapiJavascriptHttpVersion = '2.19.0'
2
2
 
3
3
  export default seamapiJavascriptHttpVersion