UNPKG

@letsparky/api-v2-client

Version:

TypeScript client for the LetsParky API V2

599 lines (598 loc) 22.7 kB
import { ApiClient } from './client'; import { Device, DeviceWithDistance, DeviceLocationSearchResponse, CreateDeviceRequest, UpdateDeviceRequest, AssignDeviceRequest, UserDevice, DeviceFilters, NearbyDevicesParams, DeviceTenantAssignParams, DeviceParkingAreaAssignParams, DeviceParkingAreaAssociation, ApiResponse, PaginationParams, PaginatedResponse, DeviceByQrResponse, QrDataCreateParams, QrDataUpdateParams, QrDataFilters, QrDataInfo, QrDataBulkCreateParams, QrDataBulkAssignParams, QrDataValidationResponse, QrDataOperationResponse, DeviceQrSummary } from './types'; /** * Device management client for the LetsParky API. * * This class provides comprehensive device management functionality including: * - Device CRUD operations (Create, Read, Update, Delete) * - Location-based device search * - User and tenant device assignments * - Device status management (activate, deactivate, block, unblock) * - Advanced filtering and pagination * * @example * ```typescript * const client = new ApiClient({ apiKey: 'your-api-key' }); * const devices = new Devices(client); * * // List all devices * const allDevices = await devices.list(); * * // Create a new device * const newDevice = await devices.create({ * name: 'Parking Sensor 1', * type: 'sensor', * location: { lat: 40.7128, lng: -74.0060 } * }); * * // Find nearby devices * const nearbyDevices = await devices.searchNearby({ * lat: 40.7128, * lng: -74.0060, * radius: 1000 * }); * ``` * * @since 1.0.0 */ export declare class Devices { private client; /** * Creates a new Devices instance. * * @param client - The ApiClient instance to use for API requests * * @since 1.0.0 */ constructor(client: ApiClient); /** * Retrieves a list of all devices. * * This method returns all devices that the authenticated user has access to. * For paginated results, use `listPaginated()` instead. * * @returns Promise resolving to an array of devices * * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When the API returns an error response * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * const response = await devices.list(); * console.log(`Found ${response.data.length} devices`); * ``` * * @since 1.0.0 */ list(): Promise<Device[]>; /** * Retrieves a paginated list of devices with optional filtering. * * This method provides pagination support and basic filtering capabilities. * For advanced filtering, use `listWithFilters()` instead. * * @param paginationParams - Pagination parameters (page, limit, sort, order) * @param filters - Optional basic filter parameters * @param filters.status - Filter by device status ('active' or 'inactive') * @param filters.type - Filter by device type * @param filters.name - Filter by device name (partial match) * @returns Promise resolving to paginated device results * * @throws {ValidationError} When pagination parameters are invalid * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When the API returns an error response * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * // Get first page with 10 devices * const response = await devices.listPaginated({ page: 1, limit: 10 }); * * // Get active sensors, sorted by name * const activeSensors = await devices.listPaginated( * { page: 1, limit: 20, sort: 'name', order: 'asc' }, * { status: 'active', type: 'sensor' } * ); * * console.log(`Page ${response.page} of ${response.pages}`); * console.log(`${response.data.length} devices on this page`); * ``` * * @since 1.0.0 */ listPaginated(paginationParams: PaginationParams, filters?: DeviceFilters): Promise<PaginatedResponse<Device>>; /** * Retrieves devices with advanced filtering capabilities. * * This method provides comprehensive filtering options including status arrays, * tenant filtering, and public/private device filtering. * * @param filters - Advanced device filter parameters * @returns Promise resolving to filtered and paginated device results * * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When the API returns an error response * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * // Get active and inactive sensors for a specific tenant * const response = await devices.listWithFilters({ * status: ['ACTIVE', 'INACTIVE'], * type: ['sensor', 'gateway'], * tenant_id: 'tenant-123', * is_public: true, * page: 1, * limit: 50 * }); * ``` * * @since 1.0.0 */ listWithFilters(filters?: DeviceFilters): Promise<ApiResponse<PaginatedResponse<Device>>>; /** * Validates and serializes coordinates for location-based queries. */ private buildLocationSearchParams; /** * Searches for devices near a specific location. * * This method finds devices within a specified radius of the given coordinates * and returns them with distance information. Results are sorted by distance. * * @param params - Location search parameters * @returns Promise resolving to nearby devices with distance information * * @throws {ValidationError} When location parameters are invalid * @throws {ApiError} When the API returns an error response * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * // Find devices within 500 meters of coordinates * const nearbyDevices = await devices.searchNearby({ * lat: 40.7831, * lng: -73.9712, * radius: 500, * page: 1, * limit: 20 * }); * * nearbyDevices.data.forEach(device => { * console.log(`${device.name}: ${device.distance}m away`); * }); * ``` * * @since 1.0.0 */ searchNearby(params: NearbyDevicesParams): Promise<ApiResponse<DeviceWithDistance[]>>; /** * Searches for devices around a location using the public search endpoint. * * Wraps `GET /devices/search/location` and returns the raw device list with * pagination metadata as described in the API specification. */ searchByLocation(params: NearbyDevicesParams): Promise<ApiResponse<DeviceLocationSearchResponse>>; /** * Retrieves a specific device by its ID. * * This method fetches detailed information about a single device. * The device ID must be a valid UUID format. * * @param deviceId - The unique identifier of the device to retrieve * @returns Promise resolving to the device details * * @throws {ValidationError} When the device ID is invalid or missing * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When the device is not found or access is denied * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * try { * const device = await devices.get('device-uuid-here'); * console.log(`Device: ${device.data.name} (${device.data.type})`); * } catch (error) { * if (error instanceof ApiError && error.status === 404) { * console.log('Device not found'); * } * } * ``` * * @since 1.0.0 */ get(deviceId: string): Promise<ApiResponse<Device>>; /** * Retrieves a specific public device by its ID. * * This method fetches detailed information about a single public device with restricted fields. * The device ID must be a valid UUID format. * * @param deviceId - The unique identifier of the device to retrieve * @returns Promise resolving to the device details * * @throws {ValidationError} When the device ID is invalid or missing * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When the device is not found or access is denied * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * try { * const device = await devices.get('device-uuid-here'); * console.log(`Device: ${device.data.name} (${device.data.type})`); * } catch (error) { * if (error instanceof ApiError && error.status === 404) { * console.log('Device not found'); * } * } * ``` * * @since 1.0.3 */ getPublic(deviceId: string): Promise<ApiResponse<Device>>; /** * Retrieves detailed information about a specific device. * * This method provides extended device information that may include * additional metadata, statistics, or configuration details not available * in the basic `get()` method. * * @param deviceId - The unique identifier of the device * @returns Promise resolving to detailed device information * * @throws {ValidationError} When the device ID is invalid or missing * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When the device is not found or access is denied * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * const deviceInfo = await devices.getInfo('device-uuid-here'); * console.log(`Device info: ${JSON.stringify(deviceInfo.data, null, 2)}`); * ``` * * @since 1.0.0 */ getInfo(deviceId: string): Promise<ApiResponse<Device>>; /** * Creates a new device. * * This method creates a new device with the specified parameters. * Name and type are required fields. Location and other parameters are optional. * * @param params - Device creation parameters * @param params.name - The device name (required) * @param params.type - The device type (required) * @param params.description - Optional device description * @param params.location - Optional device location coordinates * @param params.is_public - Whether the device is publicly accessible * @param params.tenant_id - Optional tenant ID to assign the device to * @returns Promise resolving to the created device * * @throws {ValidationError} When required parameters are missing or invalid * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When device creation fails due to business rules * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * const newDevice = await devices.create({ * name: 'Parking Sensor #1', * type: 'ultrasonic_sensor', * description: 'Main entrance parking sensor', * location: { lat: 40.7128, lng: -74.0060 }, * is_public: true * }); * * console.log(`Created device: ${newDevice.data.id}`); * ``` * * @since 1.0.0 */ create(params: CreateDeviceRequest): Promise<ApiResponse<Device>>; /** * Update an existing device * @param deviceId The ID of the device to update * @param params The device update parameters * @returns Promise with the updated device */ update(deviceId: string, params: UpdateDeviceRequest): Promise<ApiResponse<Device>>; /** * Delete a device * @param deviceId The ID of the device to delete * @returns Promise with the deletion result */ delete(deviceId: string): Promise<ApiResponse<{ success: boolean; }>>; /** * Get devices for the authenticated user * @returns Promise with user's devices */ getUserDevices(scope?: 'owned' | 'all'): Promise<ApiResponse<UserDevice[]>>; /** * Get devices for a specific user * @param user_id The ID of the user * @returns Promise with user's devices */ getDevicesForUser(user_id: string): Promise<ApiResponse<Device[]>>; /** * Get devices for a specific tenant * @param tenantId The ID of the tenant * @param filters Optional filter parameters * @returns Promise with tenant's devices */ getDevicesForTenant(tenantId: string, filters?: DeviceFilters): Promise<ApiResponse<PaginatedResponse<Device>>>; /** * Assign a device to a user * @param deviceId The ID of the device * @param params Assignment parameters * @returns Promise with the assignment result */ assignToUser(deviceId: string, params: AssignDeviceRequest): Promise<ApiResponse<UserDevice>>; /** * Get users assigned to a device * @param deviceId The ID of the device * @returns Promise with assigned users */ getAssignedUsers(deviceId: string): Promise<ApiResponse<UserDevice[]>>; /** * Revoke device access from a user * @param deviceId The ID of the device * @param user_id The ID of the user * @returns Promise with the revocation result */ revokeUserAccess(deviceId: string, user_id: string): Promise<ApiResponse<{ device_id: string; user_id: string; }>>; /** * Assign a device to a tenant * @param deviceId The ID of the device * @param params Tenant assignment parameters * @returns Promise with the updated device */ assignToTenant(deviceId: string, params: DeviceTenantAssignParams): Promise<ApiResponse<Device>>; /** * Link a device to a parking area. * * Wraps `PUT /devices/{deviceId}/parking-area` and validates the required * parking area identifier before making the request. */ assignToParkingArea(deviceId: string, params: DeviceParkingAreaAssignParams): Promise<ApiResponse<DeviceParkingAreaAssociation>>; /** * Block a device * @param deviceId The ID of the device to block * @returns Promise with the blocked device */ block(deviceId: string): Promise<ApiResponse<any>>; /** * Unblock a device * @param deviceId The ID of the device to unblock * @returns Promise with the unblocked device */ unblock(deviceId: string): Promise<ApiResponse<any>>; /** * Reboot a device * @param deviceId The ID of the device to reboot * @returns Promise with the rebooted device */ reboot(deviceId: string): Promise<ApiResponse<any>>; /** * Find a device by QR data or device code * @param params Search parameters with either qr_data or device_code * @returns Promise with the found device information */ findByQr(params: { identifier: string; }): Promise<ApiResponse<DeviceByQrResponse>>; /** * Find a device by QR data or device code * @param params Search parameters with either qr_data or device_code * @returns Promise with the found device information */ findByQrPublic(params: { identifier: string; }): Promise<ApiResponse<DeviceByQrResponse>>; /** * Create QR data for a specific device * @param deviceId The ID of the device * @param params QR data creation parameters * @returns Promise with the created QR data information */ createQrData(deviceId: string, params: QrDataCreateParams): Promise<ApiResponse<{ id: string; data: string; device_code?: string; }>>; /** * Update QR data for a specific device * @param deviceId The ID of the device * @param params QR data update parameters * @returns Promise with the updated QR data information */ updateQrData(deviceId: string, params: QrDataUpdateParams): Promise<ApiResponse<{ id: string; data: string; device_code?: string; }>>; /** * Remove QR data from a specific device * @param deviceId The ID of the device * @returns Promise with the removal result */ removeQrData(deviceId: string): Promise<ApiResponse<void>>; /** * Get QR data list with filtering and pagination * @param filters Optional filter parameters * @returns Promise with paginated QR data list */ listQrData(filters?: QrDataFilters): Promise<ApiResponse<PaginatedResponse<QrDataInfo>>>; /** * Bulk create QR codes * @param params Bulk creation parameters * @returns Promise with the creation results */ bulkCreateQrData(params: QrDataBulkCreateParams): Promise<ApiResponse<QrDataOperationResponse>>; /** * Get device-QR data summary statistics * @returns Promise with summary statistics */ getQrDataSummary(): Promise<ApiResponse<DeviceQrSummary>>; /** * Bulk assign QR codes to devices * @param params Bulk assignment parameters * @returns Promise with the assignment results */ bulkAssignQrData(params: QrDataBulkAssignParams): Promise<ApiResponse<QrDataOperationResponse>>; /** * Validate QR data uniqueness * @param params Validation parameters * @returns Promise with validation results */ validateQrData(params: { identifier: string; }): Promise<ApiResponse<QrDataValidationResponse>>; /** * Delete QR data by ID * @param qrDataId The ID of the QR data to delete * @returns Promise with the deletion result */ deleteQrData(qrDataId: string): Promise<ApiResponse<void>>; /** * Factory reset a device * * This method performs a factory reset on the specified device. * Only device owners are allowed to factory reset their devices. * * @param deviceId - The unique identifier of the device to factory reset * @returns Promise resolving to the factory reset result * * @throws {ValidationError} When the device ID is invalid or missing * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When the device is not found or user lacks permission * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * try { * await devices.factoryReset('device-uuid-here'); * console.log('Device factory reset completed'); * } catch (error) { * if (error instanceof ApiError && error.status === 403) { * console.log('Only device owners can factory reset'); * } * } * ``` * * @since 1.0.0 */ factoryReset(deviceId: string): Promise<ApiResponse<void>>; /** * Check user permissions for a device * * This method checks if the authenticated user has permission to perform * a specific operation on the specified device. * * @param deviceId - The unique identifier of the device * @param operation - The operation to check permission for (operate, block, unblock, exit) * @returns Promise resolving to permission check result * * @throws {ValidationError} When the device ID is invalid or missing * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When the device is not found * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * const permission = await devices.checkPermission('device-uuid-here', 'operate'); * if (permission.data.allowed) { * console.log('User can operate the device'); * } else { * console.log('Permission denied:', permission.data.reason); * } * ``` * * @since 1.0.0 */ checkPermission(deviceId: string, operation?: 'operate' | 'block' | 'unblock' | 'exit'): Promise<ApiResponse<{ allowed: boolean; reason: string; operation: string; user_id: string; device_id: string; }>>; /** * Add owner to an unowned device * * This method adds an owner to a device that currently has no owner. * Requires the device serial number and user ID. * * @param params - Parameters for adding owner to device * @param params.serialNo - Serial number of the device (required) * @param params.user_id - ID of the user to assign as owner (required) * @param params.nickName - Optional nickname for the device * @param params.geoLat - Optional latitude coordinate * @param params.geoLng - Optional longitude coordinate * @param params.location - Optional location description * @param params.qrData - Optional QR data for the device * @param params.photo - Optional photo URL for the device * @returns Promise resolving to the add owner result * * @throws {ValidationError} When required parameters are missing or invalid * @throws {AuthenticationError} When authentication is required or fails * @throws {ApiError} When device is not found, already has owner, or user lacks permission * @throws {NetworkError} When the request fails due to network issues * * @example * ```typescript * const devices = new Devices(client); * * try { * await devices.addOwner({ * serialNo: 'DEVICE_SERIAL_123', * user_id: 'user-uuid-here', * nickName: 'My Parking Sensor', * location: 'Parking Lot A' * }); * console.log('Owner added successfully'); * } catch (error) { * if (error instanceof ApiError && error.status === 400) { * console.log('Device already has an owner or invalid request'); * } * } * ``` * * @since 1.0.0 */ addOwner(params: { serialNo: string; user_id: string; nickName?: string; geoLat?: number; geoLng?: number; location?: string; qrData?: string; photo?: string; }): Promise<ApiResponse<void>>; }