diff --git a/package-lock.json b/package-lock.json index b652ca5f..f88474ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@seamapi/blueprint": "^1.10.0", "@seamapi/fake-seam-connect": "^2.0.4", "@seamapi/smith": "^1.1.0", - "@seamapi/types": "1.1142.0", + "@seamapi/types": "1.1174.0", "@types/jsonwebtoken": "^9.0.6", "@types/node": "^24.10.9", "ava": "^8.0.1", @@ -1133,9 +1133,9 @@ } }, "node_modules/@seamapi/types": { - "version": "1.1142.0", - "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.1142.0.tgz", - "integrity": "sha512-9KjUC6yfz2jzICw8M4Fpb0MsIgTl1MQSU3ifixxY7RM7ALeJy5CVSP1PNceTJiacBraZWi6/Ufyvv8GFizP7Tg==", + "version": "1.1174.0", + "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.1174.0.tgz", + "integrity": "sha512-8BtPRk7ffQpsep8fE+USmNzRqa21hrdIONVBmj1F1tYlfYtmaijuyzsaTyQTJnjpTzCdEgy1TIglY6tV7pRPIw==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 716943c6..39373ac5 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@seamapi/blueprint": "^1.10.0", "@seamapi/fake-seam-connect": "^2.0.4", "@seamapi/smith": "^1.1.0", - "@seamapi/types": "1.1142.0", + "@seamapi/types": "1.1174.0", "@types/jsonwebtoken": "^9.0.6", "@types/node": "^24.10.9", "ava": "^8.0.1", diff --git a/src/lib/resources/access-code.ts b/src/lib/resources/access-code.ts index a2e0b68a..ce04357c 100644 --- a/src/lib/resources/access-code.ts +++ b/src/lib/resources/access-code.ts @@ -1179,6 +1179,28 @@ export type AccessCode = { */ warning_code: 'being_deleted' } /** + * Seam had been unable to reach the device for an extended period when this access code was created, so the code is unlikely to be set until the device reconnects. Check the device's connection. This warning clears automatically when the device comes back online or the code is set on the device. + */ + | { + /** + * Date and time at which Seam created the warning. + */ + created_at?: string | undefined + /** + * Date and time since which Seam has been unable to reach the device. + */ + device_unreachable_since: string + + /** + * Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. + */ + message: string + + /** + * Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. + */ + warning_code: 'device_unreachable_for_extended_period' + } /** * An unknown issue occurred with the access code. */ | { diff --git a/src/lib/resources/acs-entrance.ts b/src/lib/resources/acs-entrance.ts index eb583fc7..87146125 100644 --- a/src/lib/resources/acs-entrance.ts +++ b/src/lib/resources/acs-entrance.ts @@ -380,7 +380,7 @@ export type AcsEntrance = { */ warnings: Array< /** - * Indicates that a change in the reported device model has been detected for this Salto KS entrance, which may occur after an IQ hub reset. Access code support may be affected. See https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support for troubleshooting steps. + * Indicates that a change in the reported device model has been detected for this Salto KS entrance, which may occur after an IQ hub reset. Access code support may be affected. See https://www.seam.co/help/salto-ks-lock-loses-access-code-support for troubleshooting steps. */ | { /** diff --git a/src/lib/resources/device-provider.ts b/src/lib/resources/device-provider.ts index ff1adb53..fc0a0566 100644 --- a/src/lib/resources/device-provider.ts +++ b/src/lib/resources/device-provider.ts @@ -81,7 +81,7 @@ export type DeviceProvider = { */ can_simulate_removal?: boolean | undefined /** - * Indicates whether the camera supports streaming live video through a camera live view session. + * Indicates whether the camera can stream live video through a camera live view session. `false` while the camera is offline. */ can_stream_live_video?: boolean | undefined /** @@ -156,6 +156,7 @@ export type DeviceProvider = { | 'tapo' | 'arlo' | 'reolink' + | 'unifi_protect' | 'ical' | 'lodgify' | 'hostaway' diff --git a/src/lib/resources/device.ts b/src/lib/resources/device.ts index f0c40075..50b6572d 100644 --- a/src/lib/resources/device.ts +++ b/src/lib/resources/device.ts @@ -84,7 +84,7 @@ export type Device = { */ can_simulate_removal?: boolean | undefined /** - * Indicates whether the camera supports streaming live video through a camera live view session. + * Indicates whether the camera can stream live video through a camera live view session. `false` while the camera is offline. */ can_stream_live_video?: boolean | undefined /** @@ -173,7 +173,7 @@ export type Device = { } | undefined /** - * Type of the device. + * Type of the device. The `august_lock` and `yale_lock` values are deprecated. Use `yale_access_lock` in place of `august_lock`, and `yale_access_lock` or `yale_home_lock` in place of `yale_lock`. */ device_type: | 'akuvox_lock' @@ -193,6 +193,8 @@ export type Device = { | 'smartthings_lock' | 'wyze_lock' | 'yale_lock' + | 'yale_access_lock' + | 'yale_home_lock' | 'two_n_intercom' | 'controlbyweb_device' | 'ttlock_lock' @@ -223,6 +225,7 @@ export type Device = { | 'tapo_camera' | 'arlo_camera' | 'reolink_camera' + | 'unifi_protect_camera' | 'sonos_speaker' /** @@ -2059,6 +2062,37 @@ export type Device = { time_zone?: string | null | undefined } | undefined + /** + * Metadata for a UniFi Protect camera. + */ + unifi_protect_metadata?: + | { + /** + * Camera ID reported by UniFi Protect. + */ + camera_id?: string | undefined + /** + * Camera name reported by UniFi Protect. + */ + camera_name?: string | undefined + /** + * Whether the camera has a microphone. + */ + has_mic?: boolean | undefined + /** + * MAC address reported by the UniFi Protect camera. + */ + mac?: string | undefined + /** + * Model reported by the UniFi Protect camera. + */ + model?: string | undefined + /** + * Name of the UniFi Protect console that manages the camera. + */ + nvr_name?: string | undefined + } + | undefined /** * Metadata for an ASSA ABLOY Visionline system. */ @@ -3159,7 +3193,7 @@ export type Device = { */ warning_code: 'salto_ks_subscription_limit_almost_reached' } /** - * Indicates that a change in the reported device model has been detected for this Salto KS lock, which may occur after an IQ hub reset. Access code support may be affected. See https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support for troubleshooting steps. + * Indicates that a change in the reported device model has been detected for this Salto KS lock, which may occur after an IQ hub reset. Access code support may be affected. See https://www.seam.co/help/salto-ks-lock-loses-access-code-support for troubleshooting steps. */ | { /** @@ -3420,6 +3454,24 @@ export type Device = { * Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. */ warning_code: 'max_access_codes_reached' + } /** + * Indicates that the camera's account plan does not include cloud recording, so event media such as motion clips is unavailable. + */ + | { + /** + * Date and time at which Seam created the warning. + */ + created_at: string + + /** + * Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. + */ + message: string + + /** + * Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. + */ + warning_code: 'cloud_recording_not_enabled' } > diff --git a/src/lib/resources/phone.ts b/src/lib/resources/phone.ts index 141a72dd..ada6eb72 100644 --- a/src/lib/resources/phone.ts +++ b/src/lib/resources/phone.ts @@ -688,7 +688,7 @@ export type Phone = { */ warning_code: 'salto_ks_subscription_limit_almost_reached' } /** - * Indicates that a change in the reported device model has been detected for this Salto KS lock, which may occur after an IQ hub reset. Access code support may be affected. See https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support for troubleshooting steps. + * Indicates that a change in the reported device model has been detected for this Salto KS lock, which may occur after an IQ hub reset. Access code support may be affected. See https://www.seam.co/help/salto-ks-lock-loses-access-code-support for troubleshooting steps. */ | { /** @@ -949,6 +949,24 @@ export type Phone = { * Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. */ warning_code: 'max_access_codes_reached' + } /** + * Indicates that the camera's account plan does not include cloud recording, so event media such as motion clips is unavailable. + */ + | { + /** + * Date and time at which Seam created the warning. + */ + created_at: string + + /** + * Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. + */ + message: string + + /** + * Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. + */ + warning_code: 'cloud_recording_not_enabled' } > diff --git a/src/lib/resources/unmanaged-access-code.ts b/src/lib/resources/unmanaged-access-code.ts index 3c8d9fee..20389dc3 100644 --- a/src/lib/resources/unmanaged-access-code.ts +++ b/src/lib/resources/unmanaged-access-code.ts @@ -961,6 +961,28 @@ export type UnmanagedAccessCode = { */ warning_code: 'being_deleted' } /** + * Seam had been unable to reach the device for an extended period when this access code was created, so the code is unlikely to be set until the device reconnects. Check the device's connection. This warning clears automatically when the device comes back online or the code is set on the device. + */ + | { + /** + * Date and time at which Seam created the warning. + */ + created_at?: string | undefined + /** + * Date and time since which Seam has been unable to reach the device. + */ + device_unreachable_since: string + + /** + * Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. + */ + message: string + + /** + * Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. + */ + warning_code: 'device_unreachable_for_extended_period' + } /** * An unknown issue occurred with the access code. */ | { diff --git a/src/lib/resources/unmanaged-device.ts b/src/lib/resources/unmanaged-device.ts index 5666103a..7b48e620 100644 --- a/src/lib/resources/unmanaged-device.ts +++ b/src/lib/resources/unmanaged-device.ts @@ -84,7 +84,7 @@ export type UnmanagedDevice = { */ can_simulate_removal?: boolean | undefined /** - * Indicates whether the camera supports streaming live video through a camera live view session. + * Indicates whether the camera can stream live video through a camera live view session. `false` while the camera is offline. */ can_stream_live_video?: boolean | undefined /** @@ -128,7 +128,7 @@ export type UnmanagedDevice = { device_id: string /** - * Type of the device. + * Type of the device. The `august_lock` and `yale_lock` values are deprecated. Use `yale_access_lock` in place of `august_lock`, and `yale_access_lock` or `yale_home_lock` in place of `yale_lock`. */ device_type: | 'akuvox_lock' @@ -148,6 +148,8 @@ export type UnmanagedDevice = { | 'smartthings_lock' | 'wyze_lock' | 'yale_lock' + | 'yale_access_lock' + | 'yale_home_lock' | 'two_n_intercom' | 'controlbyweb_device' | 'ttlock_lock' @@ -178,6 +180,7 @@ export type UnmanagedDevice = { | 'tapo_camera' | 'arlo_camera' | 'reolink_camera' + | 'unifi_protect_camera' | 'sonos_speaker' /** @@ -937,7 +940,7 @@ export type UnmanagedDevice = { */ warning_code: 'salto_ks_subscription_limit_almost_reached' } /** - * Indicates that a change in the reported device model has been detected for this Salto KS lock, which may occur after an IQ hub reset. Access code support may be affected. See https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support for troubleshooting steps. + * Indicates that a change in the reported device model has been detected for this Salto KS lock, which may occur after an IQ hub reset. Access code support may be affected. See https://www.seam.co/help/salto-ks-lock-loses-access-code-support for troubleshooting steps. */ | { /** @@ -1198,6 +1201,24 @@ export type UnmanagedDevice = { * Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. */ warning_code: 'max_access_codes_reached' + } /** + * Indicates that the camera's account plan does not include cloud recording, so event media such as motion clips is unavailable. + */ + | { + /** + * Date and time at which Seam created the warning. + */ + created_at: string + + /** + * Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. + */ + message: string + + /** + * Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. + */ + warning_code: 'cloud_recording_not_enabled' } > diff --git a/src/lib/routes/access-codes/access-codes.ts b/src/lib/routes/access-codes/access-codes.ts index ee4cd861..64fcd23a 100644 --- a/src/lib/routes/access-codes/access-codes.ts +++ b/src/lib/routes/access-codes/access-codes.ts @@ -288,10 +288,10 @@ export class SeamHttpAccessCodes { /** * Returns a list of all [access codes](https://www.seam.co/docs/low-level-apis/smart-locks/access-codes). * - * Specify `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`. + * Without `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`, returns access codes across the workspace, or across the customer when `customer_key` is set. Use `limit` and `page_cursor` to page through them. */ list( - parameters: AccessCodesListParameters, + parameters?: AccessCodesListParameters, options: AccessCodesListOptions = {}, ): AccessCodesListRequest { return new SeamHttpRequest(this, { @@ -299,18 +299,9 @@ export class SeamHttpAccessCodes { method: 'GET', params: parameters, parameters, - hasRequiredParameters: true, + hasRequiredParameters: false, requiredParameterNames: [], - atLeastOneParameterNames: [ - 'access_code_ids', - 'access_grant_id', - 'access_grant_key', - 'access_method_id', - 'customer_key', - 'device_id', - 'search', - 'user_identifier_key', - ], + atLeastOneParameterNames: [], responseKey: 'access_codes', hasPagination: true, options, @@ -639,58 +630,48 @@ export type AccessCodesGetRequest = SeamHttpRequest< export interface AccessCodesGetOptions {} -export type AccessCodesListParameters = RequireAtLeastOne< - { - /** - * IDs of the access codes that you want to retrieve. Specify `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`. - */ - access_code_ids?: Array | undefined - /** - * ID of the access grant for which you want to list access codes. Specify `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`. - */ - access_grant_id?: string | undefined - /** - * Key of the access grant for which you want to list access codes. Specify `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`. - */ - access_grant_key?: string | undefined - /** - * ID of the access method for which you want to list access codes. Specify `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`. - */ - access_method_id?: string | undefined - /** - * Customer key for which you want to list access codes. - */ - customer_key?: string | undefined - /** - * ID of the device for which you want to list access codes. Specify `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`. - */ - device_id?: string | undefined - /** - * Numerical limit on the number of access codes to return. - */ - limit?: number | undefined - /** - * Identifies the specific page of results to return, obtained from the previous page's `next_page_cursor`. - */ - page_cursor?: string | null | undefined - /** - * String for which to search. Filters returned access codes to include all records that satisfy a partial match using `name`, `code` or `access_code_id`. - */ - search?: string | undefined - /** - * Your user ID for the user by which to filter access codes. - */ - user_identifier_key?: string | undefined - }, - | 'access_code_ids' - | 'access_grant_id' - | 'access_grant_key' - | 'access_method_id' - | 'customer_key' - | 'device_id' - | 'search' - | 'user_identifier_key' -> +export type AccessCodesListParameters = { + /** + * IDs of the access codes that you want to retrieve. + */ + access_code_ids?: Array | undefined + /** + * ID of the access grant for which you want to list access codes. + */ + access_grant_id?: string | undefined + /** + * Key of the access grant for which you want to list access codes. + */ + access_grant_key?: string | undefined + /** + * ID of the access method for which you want to list access codes. + */ + access_method_id?: string | undefined + /** + * Customer key for which you want to list access codes. + */ + customer_key?: string | undefined + /** + * ID of the device for which you want to list access codes. + */ + device_id?: string | undefined + /** + * Numerical limit on the number of access codes to return. + */ + limit?: number | undefined + /** + * Identifies the specific page of results to return, obtained from the previous page's `next_page_cursor`. + */ + page_cursor?: string | null | undefined + /** + * String for which to search. Filters returned access codes to include all records that satisfy a partial match using `name`, `code` or `access_code_id`. + */ + search?: string | undefined + /** + * Your user ID for the user by which to filter access codes. + */ + user_identifier_key?: string | undefined +} /** * @deprecated Use AccessCodesListRequest instead. diff --git a/src/lib/routes/access-grants/unmanaged/unmanaged.ts b/src/lib/routes/access-grants/unmanaged/unmanaged.ts index 6c8d5d31..c7230d62 100644 --- a/src/lib/routes/access-grants/unmanaged/unmanaged.ts +++ b/src/lib/routes/access-grants/unmanaged/unmanaged.ts @@ -257,6 +257,10 @@ export type AccessGrantsUnmanagedListParameters = { * ID of the access system by which you want to filter the list of unmanaged Access Grants. */ acs_system_id?: string | undefined + /** + * Customer key for which you want to list unmanaged Access Grants. + */ + customer_key?: string | undefined /** * Numerical limit on the number of unmanaged access grants to return. */ diff --git a/src/lib/routes/access-methods/access-methods.ts b/src/lib/routes/access-methods/access-methods.ts index aa5fbe89..5cc33e57 100644 --- a/src/lib/routes/access-methods/access-methods.ts +++ b/src/lib/routes/access-methods/access-methods.ts @@ -304,6 +304,7 @@ export class SeamHttpAccessMethods { 'access_grant_id', 'access_grant_key', 'acs_entrance_id', + 'customer_key', 'device_id', 'space_id', ], @@ -513,6 +514,10 @@ export type AccessMethodsListParameters = RequireAtLeastOne< * ID of the entrance for which you want to retrieve all access methods that grant access to it. */ acs_entrance_id?: string | undefined + /** + * Customer key for which you want to list access methods. + */ + customer_key?: string | undefined /** * ID of the device by which to filter the returned access methods. Must be combined with `access_grant_id`, `access_grant_key`, or `acs_entrance_id`. */ @@ -534,6 +539,7 @@ export type AccessMethodsListParameters = RequireAtLeastOne< | 'access_grant_id' | 'access_grant_key' | 'acs_entrance_id' + | 'customer_key' | 'device_id' | 'space_id' > diff --git a/src/lib/routes/client-sessions/client-sessions.ts b/src/lib/routes/client-sessions/client-sessions.ts index 3d939390..0f828eab 100644 --- a/src/lib/routes/client-sessions/client-sessions.ts +++ b/src/lib/routes/client-sessions/client-sessions.ts @@ -284,6 +284,7 @@ export class SeamHttpClientSessions { requiredParameterNames: [], atLeastOneParameterNames: [], responseKey: 'client_sessions', + hasPagination: true, options, }) } @@ -494,6 +495,18 @@ export type ClientSessionsListParameters = { * ID of the [Connect Webview](https://www.seam.co/docs/core-concepts/connect-webviews) for which you want to retrieve client sessions. Specify `null` to retrieve client sessions that are not associated with a Connect Webview. */ connect_webview_id?: string | null | undefined + /** + * Customer key for which you want to list client sessions. + */ + customer_key?: string | undefined + /** + * Maximum number of records to return per page. + */ + limit?: number | undefined + /** + * Identifies the specific page of results to return, obtained from the previous page's `next_page_cursor`. + */ + page_cursor?: string | null | undefined /** * Your user ID for the user by which you want to filter client sessions. */ @@ -515,7 +528,7 @@ export type ClientSessionsListResponse = { client_sessions: Array } -export type ClientSessionsListRequest = SeamHttpRequest< +export type ClientSessionsListRequest = SeamPaginatedRequest< ClientSessionsListResponse, 'client_sessions' > diff --git a/src/lib/routes/connect-webviews/connect-webviews.ts b/src/lib/routes/connect-webviews/connect-webviews.ts index d75cb132..57ad65ee 100644 --- a/src/lib/routes/connect-webviews/connect-webviews.ts +++ b/src/lib/routes/connect-webviews/connect-webviews.ts @@ -332,6 +332,7 @@ export type ConnectWebviewsCreateParameters = { | 'tapo' | 'arlo' | 'reolink' + | 'unifi_protect' | 'ical' | 'lodgify' | 'hostaway' diff --git a/src/lib/routes/customers/customers.ts b/src/lib/routes/customers/customers.ts index 6a599901..5bd9a2ce 100644 --- a/src/lib/routes/customers/customers.ts +++ b/src/lib/routes/customers/customers.ts @@ -583,6 +583,94 @@ export type CustomersCreatePortalParameters = { * Starting date and time for the access grant. */ starts_at?: string | Date | Temporal.Instant | undefined + /** + * Parts of the reservation that each get their own access, for example one per room. Each sub-reservation inherits the reservation's name, times, preferred code, guest and custom metadata unless it sets its own, and must set its own location keys. A reservation with sub-reservations must not set location keys itself. Sending this list replaces the reservation's sub-reservations: any not included are removed, and an empty list removes all of them. Omitting it leaves existing sub-reservations unchanged. + */ + sub_reservations?: + | Array<{ + /** + * Building keys associated with the access grant. + */ + building_keys?: Array | undefined + /** + * Common area keys associated with the access grant. + */ + common_area_keys?: Array | undefined + /** + * Set key:value pairs for filtering sub-reservations by custom criteria. Merged over the reservation's custom metadata. Set a key to `null` or to an empty string to remove that key from the custom metadata. + */ + custom_metadata?: + Record | undefined + /** + * Ending date and time for the access grant. + */ + ends_at?: string | Date | Temporal.Instant | undefined + /** + * Facility keys associated with the access grant. + */ + facility_keys?: Array | undefined + /** + * Guest key associated with the access grant. + */ + guest_key?: string | undefined + /** + * Whether this is the reservation's primary sub-reservation, for example the room the guest stays in. Only the primary sub-reservation passes the guest's phone number to access systems that require a phone number to be unique per user. At most one sub-reservation of a reservation can be primary. If none is, the first sub-reservation in the list is primary. + */ + is_primary?: boolean | undefined + /** + * Listing keys associated with the access grant. + */ + listing_keys?: Array | undefined + /** + * Your name for this access grant resource. + */ + name?: string | undefined + /** + * Preferred PIN code to use when creating access for this reservation. Set to `null` to remove a previously set preferred code, so that access falls back to an automatically generated code. Omitting this field keeps any previously set preferred code. + */ + preferred_code?: string | null | undefined + /** + * Property keys associated with the access grant. + */ + property_keys?: Array | undefined + /** + * Resident key associated with the access grant. + */ + resident_key?: string | undefined + /** + * Room keys associated with the access grant. + */ + room_keys?: Array | undefined + /** + * Space keys associated with the access grant. + */ + space_keys?: Array | undefined + /** + * Starting date and time for the access grant. + */ + starts_at?: string | Date | Temporal.Instant | undefined + /** + * Your identifier for the sub-reservation. Must be unique across all your reservations and sub-reservations, and stay with the same reservation. + */ + sub_reservation_key?: string | undefined + /** + * Tenant key associated with the access grant. + */ + tenant_key?: string | undefined + /** + * Unit keys associated with the access grant. + */ + unit_keys?: Array | undefined + /** + * User identity key associated with the access grant. + */ + user_identity_key?: string | undefined + /** + * User key associated with the access grant. + */ + user_key?: string | undefined + }> + | undefined /** * Tenant key associated with the access grant. */ @@ -1586,6 +1674,93 @@ export type CustomersPushDataParameters = { * Starting date and time for the access grant. */ starts_at?: string | Date | Temporal.Instant | undefined + /** + * Parts of the reservation that each get their own access, for example one per room. Each sub-reservation inherits the reservation's name, times, preferred code, guest and custom metadata unless it sets its own, and must set its own location keys. A reservation with sub-reservations must not set location keys itself. Sending this list replaces the reservation's sub-reservations: any not included are removed, and an empty list removes all of them. Omitting it leaves existing sub-reservations unchanged. + */ + sub_reservations?: + | Array<{ + /** + * Building keys associated with the access grant. + */ + building_keys?: Array | undefined + /** + * Common area keys associated with the access grant. + */ + common_area_keys?: Array | undefined + /** + * Set key:value pairs for filtering sub-reservations by custom criteria. Merged over the reservation's custom metadata. Set a key to `null` or to an empty string to remove that key from the custom metadata. + */ + custom_metadata?: Record | undefined + /** + * Ending date and time for the access grant. + */ + ends_at?: string | Date | Temporal.Instant | undefined + /** + * Facility keys associated with the access grant. + */ + facility_keys?: Array | undefined + /** + * Guest key associated with the access grant. + */ + guest_key?: string | undefined + /** + * Whether this is the reservation's primary sub-reservation, for example the room the guest stays in. Only the primary sub-reservation passes the guest's phone number to access systems that require a phone number to be unique per user. At most one sub-reservation of a reservation can be primary. If none is, the first sub-reservation in the list is primary. + */ + is_primary?: boolean | undefined + /** + * Listing keys associated with the access grant. + */ + listing_keys?: Array | undefined + /** + * Your name for this access grant resource. + */ + name?: string | undefined + /** + * Preferred PIN code to use when creating access for this reservation. Set to `null` to remove a previously set preferred code, so that access falls back to an automatically generated code. Omitting this field keeps any previously set preferred code. + */ + preferred_code?: string | null | undefined + /** + * Property keys associated with the access grant. + */ + property_keys?: Array | undefined + /** + * Resident key associated with the access grant. + */ + resident_key?: string | undefined + /** + * Room keys associated with the access grant. + */ + room_keys?: Array | undefined + /** + * Space keys associated with the access grant. + */ + space_keys?: Array | undefined + /** + * Starting date and time for the access grant. + */ + starts_at?: string | Date | Temporal.Instant | undefined + /** + * Your identifier for the sub-reservation. Must be unique across all your reservations and sub-reservations, and stay with the same reservation. + */ + sub_reservation_key?: string | undefined + /** + * Tenant key associated with the access grant. + */ + tenant_key?: string | undefined + /** + * Unit keys associated with the access grant. + */ + unit_keys?: Array | undefined + /** + * User identity key associated with the access grant. + */ + user_identity_key?: string | undefined + /** + * User key associated with the access grant. + */ + user_key?: string | undefined + }> + | undefined /** * Tenant key associated with the access grant. */ diff --git a/src/lib/routes/devices/devices.ts b/src/lib/routes/devices/devices.ts index bad4188f..c25113cc 100644 --- a/src/lib/routes/devices/devices.ts +++ b/src/lib/routes/devices/devices.ts @@ -357,6 +357,8 @@ export type DevicesListParameters = { | 'smartthings_lock' | 'wyze_lock' | 'yale_lock' + | 'yale_access_lock' + | 'yale_home_lock' | 'two_n_intercom' | 'controlbyweb_device' | 'ttlock_lock' @@ -387,6 +389,7 @@ export type DevicesListParameters = { | 'tapo_camera' | 'arlo_camera' | 'reolink_camera' + | 'unifi_protect_camera' | 'sonos_speaker' | undefined /** @@ -411,6 +414,8 @@ export type DevicesListParameters = { | 'smartthings_lock' | 'wyze_lock' | 'yale_lock' + | 'yale_access_lock' + | 'yale_home_lock' | 'two_n_intercom' | 'controlbyweb_device' | 'ttlock_lock' @@ -441,6 +446,7 @@ export type DevicesListParameters = { | 'tapo_camera' | 'arlo_camera' | 'reolink_camera' + | 'unifi_protect_camera' | 'sonos_speaker' > | undefined @@ -479,6 +485,7 @@ export type DevicesListParameters = { | 'controlbyweb' | 'tedee' | 'keyincode' + | 'ubiquiti' | 'akiles' | 'aqara' | 'ecobee' @@ -500,6 +507,7 @@ export type DevicesListParameters = { | 'tapo' | 'arlo' | 'reolink' + | 'unifi_protect' | 'ical' | 'lodgify' | 'hostaway' diff --git a/src/lib/routes/devices/unmanaged/unmanaged.ts b/src/lib/routes/devices/unmanaged/unmanaged.ts index be23e60d..d1f89a33 100644 --- a/src/lib/routes/devices/unmanaged/unmanaged.ts +++ b/src/lib/routes/devices/unmanaged/unmanaged.ts @@ -304,6 +304,8 @@ export type DevicesUnmanagedListParameters = { | 'smartthings_lock' | 'wyze_lock' | 'yale_lock' + | 'yale_access_lock' + | 'yale_home_lock' | 'two_n_intercom' | 'controlbyweb_device' | 'ttlock_lock' @@ -334,6 +336,7 @@ export type DevicesUnmanagedListParameters = { | 'tapo_camera' | 'arlo_camera' | 'reolink_camera' + | 'unifi_protect_camera' | 'sonos_speaker' | undefined /** @@ -358,6 +361,8 @@ export type DevicesUnmanagedListParameters = { | 'smartthings_lock' | 'wyze_lock' | 'yale_lock' + | 'yale_access_lock' + | 'yale_home_lock' | 'two_n_intercom' | 'controlbyweb_device' | 'ttlock_lock' @@ -388,6 +393,7 @@ export type DevicesUnmanagedListParameters = { | 'tapo_camera' | 'arlo_camera' | 'reolink_camera' + | 'unifi_protect_camera' | 'sonos_speaker' > | undefined @@ -426,6 +432,7 @@ export type DevicesUnmanagedListParameters = { | 'controlbyweb' | 'tedee' | 'keyincode' + | 'ubiquiti' | 'akiles' | 'aqara' | 'ecobee' @@ -447,6 +454,7 @@ export type DevicesUnmanagedListParameters = { | 'tapo' | 'arlo' | 'reolink' + | 'unifi_protect' | 'ical' | 'lodgify' | 'hostaway' diff --git a/src/lib/routes/events/events.ts b/src/lib/routes/events/events.ts index 71e982ed..ee26cfb2 100644 --- a/src/lib/routes/events/events.ts +++ b/src/lib/routes/events/events.ts @@ -163,7 +163,7 @@ export class SeamHttpEvents { } /** - * Returns a specified event. This endpoint returns the same event that would be sent to a [webhook](https://www.seam.co/docs/developer-tools/webhooks), but it enables you to retrieve an event that already took place. + * Returns a specified event. This endpoint returns the same event that would be sent to a [webhook](https://www.seam.co/docs/developer-tools/webhooks), but it enables you to retrieve an event that already took place. Events older than 90 days are not returned. */ get( parameters: EventsGetParameters, @@ -183,7 +183,7 @@ export class SeamHttpEvents { } /** - * Returns a list of all events. This endpoint returns the same events that would be sent to a [webhook](https://www.seam.co/docs/developer-tools/webhooks), but it enables you to filter or see events that already took place. + * Returns a list of all events. This endpoint returns the same events that would be sent to a [webhook](https://www.seam.co/docs/developer-tools/webhooks), but it enables you to filter or see events that already took place. Only events from the last 90 days are returned. */ list( parameters: EventsListParameters, @@ -313,7 +313,7 @@ export type EventsListParameters = RequireAtLeastOne< */ acs_user_id?: string | undefined /** - * Lower and upper timestamps to define an exclusive interval containing the events that you want to list. You must include `since` or `between`. + * Lower and upper timestamps to define an exclusive interval containing the events that you want to list. You must include `since` or `between`. Only events from the last 90 days are returned, so a lower timestamp older than 90 days is treated as 90 days ago. */ between?: Array | undefined /** @@ -585,7 +585,7 @@ export type EventsListParameters = RequireAtLeastOne< */ limit?: number | undefined /** - * Timestamp to indicate the beginning generation time for the events that you want to list. You must include `since` or `between`. + * Timestamp to indicate the beginning generation time for the events that you want to list. You must include `since` or `between`. Only events from the last 90 days are returned, so a `since` older than 90 days is treated as 90 days ago. */ since?: string | undefined /** diff --git a/src/lib/routes/locks/locks.ts b/src/lib/routes/locks/locks.ts index 38a1e5cc..b8dcf7d8 100644 --- a/src/lib/routes/locks/locks.ts +++ b/src/lib/routes/locks/locks.ts @@ -375,6 +375,8 @@ export type LocksListParameters = { | 'smartthings_lock' | 'wyze_lock' | 'yale_lock' + | 'yale_access_lock' + | 'yale_home_lock' | 'two_n_intercom' | 'controlbyweb_device' | 'ttlock_lock' @@ -413,6 +415,8 @@ export type LocksListParameters = { | 'smartthings_lock' | 'wyze_lock' | 'yale_lock' + | 'yale_access_lock' + | 'yale_home_lock' | 'two_n_intercom' | 'controlbyweb_device' | 'ttlock_lock' diff --git a/src/lib/routes/seam-http-endpoints.ts b/src/lib/routes/seam-http-endpoints.ts index c15fd3a4..013073a1 100644 --- a/src/lib/routes/seam-http-endpoints.ts +++ b/src/lib/routes/seam-http-endpoints.ts @@ -1002,10 +1002,10 @@ export class SeamHttpEndpoints { /** * Returns a list of all [access codes](https://www.seam.co/docs/low-level-apis/smart-locks/access-codes). * - * Specify `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`. + * Without `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`, returns access codes across the workspace, or across the customer when `customer_key` is set. Use `limit` and `page_cursor` to page through them. */ get '/access_codes/list'(): ( - parameters: AccessCodesListParameters, + parameters?: AccessCodesListParameters, options?: AccessCodesListOptions, ) => AccessCodesListRequest { const { client, defaults } = this @@ -2910,7 +2910,7 @@ export class SeamHttpEndpoints { } /** - * Returns a specified event. This endpoint returns the same event that would be sent to a [webhook](https://www.seam.co/docs/developer-tools/webhooks), but it enables you to retrieve an event that already took place. + * Returns a specified event. This endpoint returns the same event that would be sent to a [webhook](https://www.seam.co/docs/developer-tools/webhooks), but it enables you to retrieve an event that already took place. Events older than 90 days are not returned. */ get '/events/get'(): ( parameters: EventsGetParameters, @@ -2926,7 +2926,7 @@ export class SeamHttpEndpoints { } /** - * Returns a list of all events. This endpoint returns the same events that would be sent to a [webhook](https://www.seam.co/docs/developer-tools/webhooks), but it enables you to filter or see events that already took place. + * Returns a list of all events. This endpoint returns the same events that would be sent to a [webhook](https://www.seam.co/docs/developer-tools/webhooks), but it enables you to filter or see events that already took place. Only events from the last 90 days are returned. */ get '/events/list'(): ( parameters: EventsListParameters, @@ -4451,6 +4451,7 @@ export type SeamHttpEndpointPaginatedQueryPaths = | '/acs/entrances/list' | '/acs/users/list' | '/action_attempts/list' + | '/client_sessions/list' | '/connect_webviews/list' | '/connected_accounts/list' | '/devices/list' diff --git a/src/lib/routes/user-identities/user-identities.ts b/src/lib/routes/user-identities/user-identities.ts index 3e989965..1a968817 100644 --- a/src/lib/routes/user-identities/user-identities.ts +++ b/src/lib/routes/user-identities/user-identities.ts @@ -656,6 +656,10 @@ export type UserIdentitiesListParameters = { * `acs_system_id` of the credential manager by which you want to filter the list of user identities. */ credential_manager_acs_system_id?: string | undefined + /** + * Customer key for which you want to list user identities. + */ + customer_key?: string | undefined /** * Maximum number of records to return per page. */ diff --git a/test/seam/connect/request-parameters.test.ts b/test/seam/connect/request-parameters.test.ts index 8b99e026..aac01367 100644 --- a/test/seam/connect/request-parameters.test.ts +++ b/test/seam/connect/request-parameters.test.ts @@ -2,6 +2,8 @@ import test from 'ava' import { SeamHttp } from '@seamapi/http/connect' +import { assertValidRequestParameters } from 'lib/request-parameters.js' + const seam = SeamHttp.fromApiKey('seam_apikey1_token') const assertDatetimeParameterTypes = (instant: Temporal.Instant): void => { @@ -93,30 +95,32 @@ test('endpoint rejects required parameters with only undefined values', async (t ) }) -test('endpoint rejects required parameters satisfied only by pagination parameters', async (t) => { - await t.throwsAsync( - // @ts-expect-error Verify pagination parameters do not satisfy RequireAtLeastOne. - async () => await seam.accessCodes.list({ limit: 10 }), - { - instanceOf: TypeError, - message: 'At least one parameter is required for /access_codes/list', - }, - ) +test('endpoint rejects required parameters satisfied only by pagination parameters', (t) => { + const assertValidParameters = (parameters: Record): void => + assertValidRequestParameters( + parameters, + '/test/list', + true, + [], + ['device_id'], + ) + + const error = t.throws(() => assertValidParameters({ limit: 10 }), { + instanceOf: TypeError, + message: 'At least one parameter is required for /test/list', + }) + t.truthy(error) - await t.throwsAsync( - async () => - // @ts-expect-error Verify a page cursor does not satisfy RequireAtLeastOne. - await seam.accessCodes.list({ limit: 10, page_cursor: 'some-cursor' }), + t.throws( + () => assertValidParameters({ limit: 10, page_cursor: 'some-cursor' }), { instanceOf: TypeError, - message: 'At least one parameter is required for /access_codes/list', + message: 'At least one parameter is required for /test/list', }, ) -}) -test('endpoint accepts a filter parameter along with pagination parameters', (t) => { t.notThrows(() => - seam.accessCodes.list({ device_id: 'device-id', limit: 10 }), + assertValidParameters({ device_id: 'device-id', limit: 10 }), ) }) diff --git a/test/seam/connect/seam-paginator.test.ts b/test/seam/connect/seam-paginator.test.ts index c17d4209..877c9815 100644 --- a/test/seam/connect/seam-paginator.test.ts +++ b/test/seam/connect/seam-paginator.test.ts @@ -4,6 +4,8 @@ import nock from 'nock' import { type Device, SeamHttp, SeamPaginator } from '@seamapi/http/connect' +import { SeamHttpRequest } from 'lib/seam-http-request.js' + test('SeamPaginator: creates a SeamPaginator', async (t) => { const { seed, endpoint } = await getTestServer(t) const seam = SeamHttp.fromApiKey(seed.seam_apikey1_token, { endpoint }) @@ -221,18 +223,29 @@ test('SeamPaginator: validates request parameters before fetching a page', async let requestCount = 0 seam.client.interceptors.request.use((config) => { - if (config.url === '/access_codes/list') requestCount++ + if (config.url === '/test/list') requestCount++ return config }) - const pages = seam.createPaginator( - // @ts-expect-error Verify an invalid request is rejected when paginated. - seam.accessCodes.list({}), + const request = new SeamHttpRequest<{ items: unknown[] }, 'items', true>( + seam, + { + pathname: '/test/list', + method: 'GET', + params: {}, + parameters: {}, + hasRequiredParameters: true, + requiredParameterNames: [], + atLeastOneParameterNames: ['device_id'], + responseKey: 'items', + hasPagination: true, + }, ) + const pages = seam.createPaginator(request) await t.throwsAsync(async () => await pages.firstPage(), { instanceOf: TypeError, - message: 'At least one parameter is required for /access_codes/list', + message: 'At least one parameter is required for /test/list', }) t.is(requestCount, 0)