Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] typeof selectDevice function #118

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Neurosity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Focus } from "./types/focus";
import { getLabels } from "./utils/subscription";
import { BrainwavesLabel, Epoch, PowerByBand, PSD } from "./types/brainwaves";
import { Accelerometer } from "./types/accelerometer";
import { DeviceInfo, OSVersion } from "./types/deviceInfo";
import { DeviceInfo, DeviceSelector, OSVersion } from "./types/deviceInfo";
import { DeviceStatus, STATUS } from "./types/status";
import { Action } from "./types/actions";
import { HapticEffects } from "./types/hapticEffects";
Expand Down Expand Up @@ -526,7 +526,7 @@ export class Neurosity {
* For more info, check out the "Device Selection" guide.
*/
public async selectDevice(
deviceSelector: (devices: DeviceInfo[]) => DeviceInfo
deviceSelector: DeviceSelector
): Promise<DeviceInfo> {
const [hasOAuthError, OAuthError] = validateOAuthScopeForFunctionName(
this.cloudClient.userClaims,
Expand Down
68 changes: 67 additions & 1 deletion src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { EmailAndPassword } from "../types/credentials";
import { ChangeSettings } from "../types/settings";
import { Subscription } from "../types/subscriptions";
import { DeviceStatus } from "../types/status";
import { DeviceInfo, DeviceSelector, OSVersion } from "../types/deviceInfo";
import { DeviceInfo, DeviceSelector, DeviceSelectorFunction, OSVersion } from "../types/deviceInfo";
import { UserClaims } from "../types/user";
import { OAuthRemoveResponse } from "../types/oauth";
import { Experiment } from "../types/experiment";
Expand Down Expand Up @@ -250,6 +250,72 @@ export class CloudClient implements Client {
return !!selectedDevice;
}

private async finalizeDeviceSelection(device: DeviceInfo): Promise<DeviceInfo> {
const hasPermission = await this.firebaseUser.hasDevicePermission(
device.deviceId
);

if (!hasPermission) {
return Promise.reject(`Rejected device access due to permissions.`);
}

this._selectedDevice.next(device);

return device;
}

/**
* Selects a device from the list of available devices based on a key-value pair of the device information.
*
* @template K The type of the key.
* @param {K} key The key to search for in the device information.
* @param {DeviceInfo[K]} value The value to match with the specified key.
* @returns {Promise<DeviceInfo>} A promise that resolves to the selected device information.
* @throws {Error} If no devices are found for the user or if no device is found with the specified key-value pair.
*/
public async selectDeviceByKeyValue<K extends keyof DeviceInfo>(
key: K,
value: DeviceInfo[K]
): Promise<DeviceInfo> {
const devices = await this.getDevices();
if (!devices.length) {
throw new Error("No devices found for this user.");
}

const selectedDevice = devices.find(device => JSON.stringify(device[key]) === JSON.stringify(value));
if (!selectedDevice) {
throw new Error("Device not found with specified key-value pair.");
}

return this.finalizeDeviceSelection(selectedDevice);
}

/**
* Selects a device based on the provided device selector function.
*
* @param deviceSelector The device selector function used to select a device from the available devices.
* @returns A promise that resolves to the selected device information.
* @throws {Error} An error if no devices are found for the user or if the specified device is not found.
*/
public async selectDeviceBySelector(
deviceSelector: DeviceSelectorFunction
): Promise<DeviceInfo> {
const devices = await this.getDevices();
if (!devices.length) {
throw new Error("No devices found for this user.");
}

const selectedDevice = deviceSelector(devices);
if (!selectedDevice) {
throw new Error("Device not found with specified selector.");
}

return this.finalizeDeviceSelection(selectedDevice);
}

/**
* @deprecated Use `selectDeviceByKeyValue` or `selectDeviceBySelector` instead.
*/
public async selectDevice(
deviceSelector: DeviceSelector
): Promise<DeviceInfo> {
Expand Down
2 changes: 1 addition & 1 deletion src/types/deviceInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ export interface DeviceInfo {
}

type DeviceSelectorKeyValue = [string, string | number | string[]];
type DeviceSelectorFunction = (devices: DeviceInfo[]) => DeviceInfo;
export type DeviceSelectorFunction = (devices: DeviceInfo[]) => DeviceInfo;

export type DeviceSelector = DeviceSelectorKeyValue | DeviceSelectorFunction;