You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
4.8 KiB
161 lines
4.8 KiB
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}`); |
|
} |
|
} |
|
} |
|
}
|
|
|