@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.
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/lib/client.d.ts +12 -0
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js.map +1 -1
- package/lib/options.d.ts +105 -0
- package/lib/options.js +54 -0
- package/lib/options.js.map +1 -1
- package/lib/request-options.d.ts +13 -0
- package/lib/request-options.js +3 -0
- package/lib/request-options.js.map +1 -1
- package/lib/resolve-action-attempt.d.ts +47 -0
- package/lib/resolve-action-attempt.js +29 -0
- package/lib/resolve-action-attempt.js.map +1 -1
- package/lib/resources/device.d.ts +0 -12
- package/lib/seam-http-error.d.ts +34 -0
- package/lib/seam-http-error.js +34 -0
- package/lib/seam-http-error.js.map +1 -1
- package/lib/seam-http-request.d.ts +31 -0
- package/lib/seam-http-request.js +31 -0
- package/lib/seam-http-request.js.map +1 -1
- package/lib/seam-paginator.d.ts +28 -0
- package/lib/seam-paginator.js +25 -0
- package/lib/seam-paginator.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +3 -2
- package/src/index.ts +5 -0
- package/src/lib/client.ts +14 -0
- package/src/lib/index.ts +3 -0
- package/src/lib/options.ts +105 -0
- package/src/lib/request-options.ts +13 -0
- package/src/lib/resolve-action-attempt.ts +48 -0
- package/src/lib/resources/device.ts +0 -12
- package/src/lib/seam-http-error.ts +38 -0
- package/src/lib/seam-http-request.ts +31 -0
- package/src/lib/seam-paginator.ts +28 -0
- package/src/lib/version.ts +1 -1
|
@@ -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
|
> {
|
package/src/lib/version.ts
CHANGED