Alex Mikhalev
6 years ago
2 changed files with 164 additions and 5 deletions
@ -0,0 +1,161 @@ |
|||||||
|
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> { |
||||||
|
let 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}'`); |
||||||
|
} |
||||||
|
let 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}`); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue