Files
flipper/src/utils/clientUtils.tsx
John Knox 0bf905e02f Replace all manual pluginKey parsing with a utility
Summary:
Ok this diff got a bit bigger than expected, but I think it makes it easier to understand what "plugin keys" are, and makes them less prone to error.

Previously pluginKeys were composed of: clientId#pluginName, where clientId was itself: app#os#device#device_id

But also, there were some plugin keys where the clientId was a device_id.

Now you deconstruct a plugin key, and will get a tagged object with type: 'device' or 'client', and the properties that they each have.

There is now no custom parsing of these afaik, let's keep it that way.

Since it took me a while to figure out what all these IDs are, I've documented it a bit in clientUtils.

Reviewed By: passy

Differential Revision: D18811848

fbshipit-source-id: eed2e2b5eedafb9e27900dbcf79a389fcaffae95
2019-12-05 07:37:57 -08:00

118 lines
3.1 KiB
TypeScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import Client from '../Client';
import BaseDevice from '../devices/BaseDevice';
/* A Client uniuely identifies an app running on some device.
Always use this utility to construct and parse clientId strings.
*/
export type ClientIdConstituents = {
app: string;
os: string;
device: string;
device_id: string;
};
/* A plugin key is a string uniquely identifying an instance of a plugin.
This can be a device plugin for a particular device, or a client plugin for a particular client (app).
In the device plugin case, the "client" is the device it's connected to.
In the client plugin case (normal plugins), the "client" is the app it's connected to.
Always use this utility to construct and parse pluginKey strings.
*/
type PluginKeyConstituents =
| {
type: 'device';
pluginName: string;
client: string;
}
| ({
type: 'client';
pluginName: string;
client: string;
} & ClientIdConstituents);
export function currentActiveApps(
clients: Array<Client>,
selectedDevice: null | BaseDevice,
): Array<string> {
const currentActiveApps: Array<string> = clients
.map(({id}: {id: string}) => {
const appName = deconstructClientId(id).app || '';
const os = deconstructClientId(id).os || '';
return {appName, os};
})
.filter(
({os}: {os: string}) => os && selectedDevice && os == selectedDevice.os,
)
.map(client => client.appName);
return currentActiveApps;
}
export function buildClientId(clientInfo: {
app: string;
os: string;
device: string;
device_id: string;
}): string {
for (const key of ['app', 'os', 'device', 'device_id'] as Array<
keyof ClientIdConstituents
>) {
if (!clientInfo[key]) {
console.error(
`Attempted to build clientId with invalid ${key}: "${clientInfo[key]}`,
);
}
}
return `${clientInfo.app}#${clientInfo.os}#${clientInfo.device}#${clientInfo.device_id}`;
}
export function deconstructClientId(clientId: string): ClientIdConstituents {
if (!clientId || clientId.split('#').length !== 4) {
console.error(`Attempted to deconstruct invalid clientId: "${clientId}"`);
}
const [app, os, device, device_id] = clientId.split('#');
return {
app,
os,
device,
device_id,
};
}
export function deconstructPluginKey(pluginKey: string): PluginKeyConstituents {
const parts = pluginKey.split('#');
if (parts.length === 2) {
// Device plugin
return {
type: 'device',
client: parts[0],
pluginName: parts[1],
};
} else {
// Client plugin
const lastHashIndex = pluginKey.lastIndexOf('#');
const clientId = pluginKey.slice(0, lastHashIndex);
const pluginName = pluginKey.slice(lastHashIndex + 1);
if (!pluginName) {
console.error(
`Attempted to deconstruct invalid pluginKey: "${pluginKey}"`,
);
}
return {
type: 'client',
...deconstructClientId(clientId),
client: clientId,
pluginName: pluginName,
};
}
}