|
|
|
import { flags } from "@oclif/command";
|
|
|
|
import { ux } from "cli-ux";
|
|
|
|
import { capitalize } from "lodash";
|
|
|
|
import { FindConditions } from "typeorm";
|
|
|
|
|
|
|
|
import ManageCommand from "../ManageCommand";
|
|
|
|
|
|
|
|
import { Input } from "@oclif/parser/lib/flags";
|
|
|
|
import { SprinklersDevice, User } from "@server/entities";
|
|
|
|
|
|
|
|
type DeviceFlags = (typeof DeviceCommand)["flags"] extends Input<infer F>
|
|
|
|
? F
|
|
|
|
: never;
|
|
|
|
|
|
|
|
type Action = "show" | "delete" | "add-user" | "remove-user";
|
|
|
|
|
|
|
|
const VALID_ACTIONS: Action[] = [ "show", "delete", "add-user", "remove-user" ];
|
|
|
|
|
|
|
|
// tslint:disable:no-shadowed-variable
|
|
|
|
|
|
|
|
export default class DeviceCommand extends ManageCommand {
|
|
|
|
static description = "Manage devices";
|
|
|
|
|
|
|
|
static flags = {
|
|
|
|
show: flags.boolean({
|
|
|
|
char: "s",
|
|
|
|
exclusive: ["add-user", "delete"],
|
|
|
|
description: "Show devices(s)",
|
|
|
|
}),
|
|
|
|
"add-user": flags.boolean({
|
|
|
|
char: "a",
|
|
|
|
exclusive: ["show", "delete"],
|
|
|
|
description: "Add a user as owning this device (specify --username)"
|
|
|
|
}),
|
|
|
|
"remove-user": flags.boolean({
|
|
|
|
char: "r",
|
|
|
|
exclusive: ["add-user", "show", "delete"],
|
|
|
|
description: "Remove a user as owning this device (specify --username)"
|
|
|
|
}),
|
|
|
|
delete: flags.boolean({
|
|
|
|
char: "d",
|
|
|
|
exclusive: ["show", "add-user"],
|
|
|
|
description: "Delete a user (by --id or --username)"
|
|
|
|
}),
|
|
|
|
id: flags.integer({
|
|
|
|
description: "The id of the device to update or delete",
|
|
|
|
}),
|
|
|
|
name: flags.string({
|
|
|
|
description: "The name of the device, when creating or updating"
|
|
|
|
}),
|
|
|
|
deviceId: flags.string({
|
|
|
|
description: "The deviceId of the device, when creating or updating"
|
|
|
|
}),
|
|
|
|
username: flags.string({
|
|
|
|
description: "Specify a username for --show or --add-user"
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
|
|
|
|
getAction(flags: DeviceFlags): Action {
|
|
|
|
for (const action of VALID_ACTIONS) {
|
|
|
|
if (flags[action]) {
|
|
|
|
return action;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const actionFlags = VALID_ACTIONS.map(action => `--${action}`);
|
|
|
|
this.error(`Must specify an action (${actionFlags.join(', ')})`, {
|
|
|
|
exit: false,
|
|
|
|
});
|
|
|
|
return this._help();
|
|
|
|
}
|
|
|
|
|
|
|
|
getFindConditions(flags: DeviceFlags, action: Action): FindConditions<SprinklersDevice> {
|
|
|
|
const whereClause: FindConditions<SprinklersDevice> = {};
|
|
|
|
if (flags.id) {
|
|
|
|
whereClause.id = flags.id;
|
|
|
|
}
|
|
|
|
if (flags.name) {
|
|
|
|
whereClause.name = flags.name;
|
|
|
|
}
|
|
|
|
if (flags.deviceId) {
|
|
|
|
whereClause.deviceId = flags.deviceId;
|
|
|
|
}
|
|
|
|
if (false) {
|
|
|
|
this.error(`Must specify --id to ${action}`, {
|
|
|
|
exit: false
|
|
|
|
});
|
|
|
|
return this._help();
|
|
|
|
}
|
|
|
|
return whereClause;
|
|
|
|
}
|
|
|
|
|
|
|
|
async getOrDeleteDevice(flags: DeviceFlags, action: Action): Promise<SprinklersDevice | never> {
|
|
|
|
const findConditions = this.getFindConditions(flags, action);
|
|
|
|
if (action === "delete") {
|
|
|
|
const result = await this.database.sprinklersDevices.delete(findConditions);
|
|
|
|
if (result.raw[1] > 0) {
|
|
|
|
this.log(`Deleted device`);
|
|
|
|
} else {
|
|
|
|
this.error("Did not find device to delete");
|
|
|
|
}
|
|
|
|
return this.exit();
|
|
|
|
} else {
|
|
|
|
const device = await this.database.sprinklersDevices.findOne(findConditions);
|
|
|
|
if (!device) {
|
|
|
|
return this.error(`The specified device does not exist`);
|
|
|
|
}
|
|
|
|
return device;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async run() {
|
|
|
|
const parseResult = this.parse(DeviceCommand);
|
|
|
|
|
|
|
|
const flags = parseResult.flags;
|
|
|
|
const action = this.getAction(flags);
|
|
|
|
|
|
|
|
await this.connect();
|
|
|
|
|
|
|
|
if (flags.show) {
|
|
|
|
const findConditions = this.getFindConditions(flags, action);
|
|
|
|
let query = this.database.sprinklersDevices.createQueryBuilder("device")
|
|
|
|
.leftJoinAndSelect("device.users", "user")
|
|
|
|
.where(findConditions);
|
|
|
|
if (flags.username) {
|
|
|
|
query = query.where("user.username = :username", { username: flags.username });
|
|
|
|
}
|
|
|
|
const devices = await query.getMany();
|
|
|
|
if (devices.length === 0) {
|
|
|
|
this.log("No sprinklers devices found");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
this.log("Devices: ")
|
|
|
|
for (const device of devices) {
|
|
|
|
this.log(JSON.stringify(device, null, " "));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const device = await this.getOrDeleteDevice(flags, action);
|
|
|
|
|
|
|
|
if (flags["add-user"] || flags["remove-user"]) {
|
|
|
|
if (!flags.username) {
|
|
|
|
return this.error("Must specify --username for --add-user")
|
|
|
|
}
|
|
|
|
const user = await this.database.users.findByUsername(flags.username);
|
|
|
|
if (!user) {
|
|
|
|
return this.error(`Could not find user with username '${flags.username}'`);
|
|
|
|
}
|
|
|
|
const query = this.database.sprinklersDevices.createQueryBuilder()
|
|
|
|
.relation("users")
|
|
|
|
.of(device);
|
|
|
|
if (flags["add-user"]) {
|
|
|
|
await query.add(user);
|
|
|
|
this.log(`Added user '${user.username}' to device '${device.name}`);
|
|
|
|
} else {
|
|
|
|
await query.remove(user);
|
|
|
|
this.log(`Removed user '${user.username}' from device '${device.name}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|