@seamapi/react 1.34.0 → 1.36.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/README.md +1 -1
- package/dist/elements.js +3880 -3856
- package/dist/elements.js.map +1 -1
- package/lib/icons/ClimateSettingSchedule.d.ts +2 -0
- package/lib/icons/ClimateSettingSchedule.js +5 -0
- package/lib/icons/ClimateSettingSchedule.js.map +1 -0
- package/lib/icons/ThermostatCool.d.ts +2 -0
- package/lib/icons/ThermostatCool.js +5 -0
- package/lib/icons/ThermostatCool.js.map +1 -0
- package/lib/icons/ThermostatHeat.d.ts +2 -0
- package/lib/icons/ThermostatHeat.js +5 -0
- package/lib/icons/ThermostatHeat.js.map +1 -0
- package/lib/icons/ThermostatHeatCool.d.ts +2 -0
- package/lib/icons/ThermostatHeatCool.js +5 -0
- package/lib/icons/ThermostatHeatCool.js.map +1 -0
- package/lib/icons/ThermostatOff.d.ts +2 -0
- package/lib/icons/ThermostatOff.js +5 -0
- package/lib/icons/ThermostatOff.js.map +1 -0
- package/lib/seam/SeamProvider.js +16 -12
- package/lib/seam/SeamProvider.js.map +1 -1
- package/lib/seam/access-codes/use-create-access-code.js +3 -4
- package/lib/seam/access-codes/use-create-access-code.js.map +1 -1
- package/lib/seam/connect-webviews/use-create-connect-webview.js +3 -4
- package/lib/seam/connect-webviews/use-create-connect-webview.js.map +1 -1
- package/lib/seam/devices/use-toggle-lock.js +3 -4
- package/lib/seam/devices/use-toggle-lock.js.map +1 -1
- package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.d.ts +5 -0
- package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.js +29 -0
- package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.js.map +1 -0
- package/lib/seam/use-seam-client.d.ts +3 -0
- package/lib/seam/use-seam-client.js +12 -0
- package/lib/seam/use-seam-client.js.map +1 -1
- package/lib/ui/RadioField/RadioField.d.ts +1 -1
- package/lib/ui/RadioField/RadioField.js +2 -2
- package/lib/ui/RadioField/RadioField.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +2 -2
- package/src/elements.ts +1 -1
- package/src/lib/icons/ClimateSettingSchedule.tsx +25 -0
- package/src/lib/icons/ThermostatCool.tsx +23 -0
- package/src/lib/icons/ThermostatHeat.tsx +23 -0
- package/src/lib/icons/ThermostatHeatCool.tsx +27 -0
- package/src/lib/icons/ThermostatOff.tsx +21 -0
- package/src/lib/seam/SeamProvider.tsx +27 -16
- package/src/lib/seam/access-codes/use-create-access-code.ts +2 -5
- package/src/lib/seam/connect-webviews/use-create-connect-webview.ts +2 -5
- package/src/lib/seam/devices/use-toggle-lock.ts +2 -5
- package/src/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.ts +53 -0
- package/src/lib/seam/use-seam-client.ts +15 -0
- package/src/lib/ui/RadioField/RadioField.tsx +6 -5
- package/src/lib/version.ts +1 -1
|
@@ -150,13 +150,7 @@ const defaultSeamContextValue = createDefaultSeamContextValue()
|
|
|
150
150
|
export const seamContext = createContext<SeamContext>(defaultSeamContextValue)
|
|
151
151
|
|
|
152
152
|
export function useSeamContext(): SeamContext {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (context == null) {
|
|
156
|
-
throw new Error('useSeamContext must be used inside a <SeamProvider/>')
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return context
|
|
153
|
+
return useContext(seamContext)
|
|
160
154
|
}
|
|
161
155
|
|
|
162
156
|
const isSeamProviderPropsWithClient = (
|
|
@@ -167,8 +161,11 @@ const isSeamProviderPropsWithClient = (
|
|
|
167
161
|
const { client } = props
|
|
168
162
|
if (client == null) return false
|
|
169
163
|
|
|
170
|
-
|
|
171
|
-
|
|
164
|
+
const otherNonNullProps = Object.values(props).filter((v) => v != null)
|
|
165
|
+
if (otherNonNullProps.length > 0) {
|
|
166
|
+
throw new InvalidSeamProviderProps(
|
|
167
|
+
`The client prop cannot be used with ${otherNonNullProps.join(' or ')}.`
|
|
168
|
+
)
|
|
172
169
|
}
|
|
173
170
|
|
|
174
171
|
return true
|
|
@@ -183,12 +180,14 @@ const isSeamProviderPropsWithPublishableKey = (
|
|
|
183
180
|
if (publishableKey == null) return false
|
|
184
181
|
|
|
185
182
|
if ('client' in props && props.client != null) {
|
|
186
|
-
throw new
|
|
183
|
+
throw new InvalidSeamProviderProps(
|
|
184
|
+
'The client prop cannot be used with the publishableKey prop.'
|
|
185
|
+
)
|
|
187
186
|
}
|
|
188
187
|
|
|
189
188
|
if ('clientSessionToken' in props && props.clientSessionToken != null) {
|
|
190
|
-
throw new
|
|
191
|
-
'
|
|
189
|
+
throw new InvalidSeamProviderProps(
|
|
190
|
+
'The clientSessionToken prop cannot be used with the publishableKey prop.'
|
|
192
191
|
)
|
|
193
192
|
}
|
|
194
193
|
|
|
@@ -205,18 +204,30 @@ const isSeamProviderPropsWithClientSessionToken = (
|
|
|
205
204
|
if (clientSessionToken == null) return false
|
|
206
205
|
|
|
207
206
|
if ('client' in props && props.client != null) {
|
|
208
|
-
throw new
|
|
207
|
+
throw new InvalidSeamProviderProps(
|
|
208
|
+
'The client prop cannot be used with the clientSessionToken prop.'
|
|
209
|
+
)
|
|
209
210
|
}
|
|
210
211
|
|
|
211
212
|
if ('publishableKey' in props && props.publishableKey != null) {
|
|
212
|
-
throw new
|
|
213
|
-
'
|
|
213
|
+
throw new InvalidSeamProviderProps(
|
|
214
|
+
'The publishableKey prop cannot be used with the clientSessionToken prop.'
|
|
214
215
|
)
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
if ('userIdentifierKey' in props && props.userIdentifierKey != null) {
|
|
218
|
-
throw new
|
|
219
|
+
throw new InvalidSeamProviderProps(
|
|
220
|
+
'The userIdentifierKey prop cannot be used with the clientSessionToken prop.'
|
|
221
|
+
)
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
return true
|
|
222
225
|
}
|
|
226
|
+
|
|
227
|
+
class InvalidSeamProviderProps extends Error {
|
|
228
|
+
constructor(message: string) {
|
|
229
|
+
super(`SeamProvider received invalid props: ${message}`)
|
|
230
|
+
this.name = this.constructor.name
|
|
231
|
+
Error.captureStackTrace(this, this.constructor)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
SeamError,
|
|
11
11
|
} from 'seamapi'
|
|
12
12
|
|
|
13
|
-
import { useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
13
|
+
import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
14
14
|
|
|
15
15
|
export type UseCreateAccessCodeParams = never
|
|
16
16
|
export type UseCreateAccessCodeData = AccessCode
|
|
@@ -30,10 +30,7 @@ export function useCreateAccessCode(): UseMutationResult<
|
|
|
30
30
|
AccessCodeCreateRequest
|
|
31
31
|
>({
|
|
32
32
|
mutationFn: async (mutationParams: UseCreateAccessCodeMutationParams) => {
|
|
33
|
-
if (client === null)
|
|
34
|
-
throw new Error('Missing seam client')
|
|
35
|
-
}
|
|
36
|
-
|
|
33
|
+
if (client === null) throw new NullSeamClientError()
|
|
37
34
|
return await client.accessCodes.create(mutationParams)
|
|
38
35
|
},
|
|
39
36
|
onSuccess: () => {
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
SeamError,
|
|
7
7
|
} from 'seamapi'
|
|
8
8
|
|
|
9
|
-
import { useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
9
|
+
import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
10
10
|
|
|
11
11
|
export interface UseCreateConnectWebviewParams {
|
|
12
12
|
willNavigateToWebview?: boolean
|
|
@@ -32,10 +32,7 @@ export function useCreateConnectWebview({
|
|
|
32
32
|
mutationFn: async (
|
|
33
33
|
mutationParams: UseCreateConnectWebviewMutationParams
|
|
34
34
|
) => {
|
|
35
|
-
if (client
|
|
36
|
-
throw new Error('Missing seam client')
|
|
37
|
-
}
|
|
38
|
-
|
|
35
|
+
if (client === null) throw new NullSeamClientError()
|
|
39
36
|
return await client.connectWebviews.create(mutationParams)
|
|
40
37
|
},
|
|
41
38
|
onSuccess: ({ url }) => {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
type SeamError,
|
|
12
12
|
} from 'seamapi'
|
|
13
13
|
|
|
14
|
-
import { useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
14
|
+
import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
15
15
|
|
|
16
16
|
export function useToggleLock({
|
|
17
17
|
device_id: deviceId,
|
|
@@ -26,10 +26,7 @@ export function useToggleLock({
|
|
|
26
26
|
|
|
27
27
|
return useMutation<{ actionAttempt: ActionAttempt }, SeamError>({
|
|
28
28
|
mutationFn: async () => {
|
|
29
|
-
if (client
|
|
30
|
-
throw new Error('Missing seam client')
|
|
31
|
-
}
|
|
32
|
-
|
|
29
|
+
if (client === null) throw new NullSeamClientError()
|
|
33
30
|
const toggle = locked ? client.locks.unlockDoor : client.locks.lockDoor
|
|
34
31
|
return await toggle(deviceId)
|
|
35
32
|
},
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
2
|
+
import type {
|
|
3
|
+
ClimateSettingSchedule,
|
|
4
|
+
ClimateSettingSchedulesListRequest,
|
|
5
|
+
ClimateSettingSchedulesListResponse,
|
|
6
|
+
SeamError,
|
|
7
|
+
} from 'seamapi'
|
|
8
|
+
|
|
9
|
+
import { useSeamClient } from 'lib/seam/use-seam-client.js'
|
|
10
|
+
import type { UseSeamQueryResult } from 'lib/seam/use-seam-query-result.js'
|
|
11
|
+
|
|
12
|
+
export type UseClimateSettingSchedulesParams =
|
|
13
|
+
ClimateSettingSchedulesListRequest
|
|
14
|
+
export type UseClimateSettingSchedulesData = ClimateSettingSchedule[]
|
|
15
|
+
|
|
16
|
+
export function useClimateSettingSchedules(
|
|
17
|
+
params: UseClimateSettingSchedulesParams
|
|
18
|
+
): UseSeamQueryResult<
|
|
19
|
+
'climateSettingSchedules',
|
|
20
|
+
UseClimateSettingSchedulesData
|
|
21
|
+
> {
|
|
22
|
+
const { client } = useSeamClient()
|
|
23
|
+
const queryClient = useQueryClient()
|
|
24
|
+
|
|
25
|
+
const { data, ...rest } = useQuery<
|
|
26
|
+
ClimateSettingSchedulesListResponse['climate_setting_schedules'],
|
|
27
|
+
SeamError
|
|
28
|
+
>({
|
|
29
|
+
enabled: client != null,
|
|
30
|
+
queryKey: ['thermostats', 'climate_setting_schedules', 'list', params],
|
|
31
|
+
queryFn: async () => {
|
|
32
|
+
if (client == null) return []
|
|
33
|
+
return await client.thermostats.climateSettingSchedules.list(params)
|
|
34
|
+
},
|
|
35
|
+
onSuccess: (schedules) => {
|
|
36
|
+
// Prime cache for each schedule.
|
|
37
|
+
for (const schedule of schedules) {
|
|
38
|
+
queryClient.setQueryData(
|
|
39
|
+
[
|
|
40
|
+
'climate_setting_schedules',
|
|
41
|
+
'get',
|
|
42
|
+
{
|
|
43
|
+
climate_setting_schedule_id: schedule.climate_setting_schedule_id,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
schedule
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
return { ...rest, climateSettingSchedules: data }
|
|
53
|
+
}
|
|
@@ -71,6 +71,21 @@ export function useSeamClient(): {
|
|
|
71
71
|
return { client: data ?? null, isLoading, isError, error }
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
export class NullSeamClientError extends Error {
|
|
75
|
+
constructor() {
|
|
76
|
+
super(
|
|
77
|
+
[
|
|
78
|
+
'Attempted to use a null Seam client.',
|
|
79
|
+
'Either a hook using useSeamClient was called outside of a SeamProvider,',
|
|
80
|
+
'or there was an error when creating the Seam client in useSeamClient,',
|
|
81
|
+
'or useSeamClient is still loading the client.',
|
|
82
|
+
].join(' ')
|
|
83
|
+
)
|
|
84
|
+
this.name = this.constructor.name
|
|
85
|
+
Error.captureStackTrace(this, this.constructor)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
function useUserIdentifierKeyOrFingerprint(
|
|
75
90
|
userIdentifierKey: string | undefined
|
|
76
91
|
): string {
|
|
@@ -14,11 +14,12 @@ interface RadioOption<Value> {
|
|
|
14
14
|
value: Value
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
type RadioFieldContext<Value extends string> =
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
type RadioFieldContext<Value extends string> = Omit<
|
|
18
|
+
RadioFieldProps<Value>,
|
|
19
|
+
'options'
|
|
20
|
+
> | null
|
|
20
21
|
|
|
21
|
-
const radioFieldContext = createContext<RadioFieldContext<any>>(
|
|
22
|
+
const radioFieldContext = createContext<RadioFieldContext<any>>(null)
|
|
22
23
|
|
|
23
24
|
export function RadioField<Value extends string>({
|
|
24
25
|
value,
|
|
@@ -48,7 +49,7 @@ export function useRadioField<Value extends string>(): NonNullable<
|
|
|
48
49
|
RadioFieldContext<Value>
|
|
49
50
|
> {
|
|
50
51
|
const context = useContext<RadioFieldContext<Value>>(radioFieldContext)
|
|
51
|
-
if (context ===
|
|
52
|
+
if (context === null) {
|
|
52
53
|
throw new Error('useRadioField must be used within a <RadioField/>')
|
|
53
54
|
}
|
|
54
55
|
return context
|
package/src/lib/version.ts
CHANGED