Add new CLI command: Search

This commit is contained in:
Jesse Wierzbinski 2023-11-29 08:46:34 -10:00
parent e01e92c9ce
commit 91838e7aec
No known key found for this signature in database
3 changed files with 151 additions and 21 deletions

BIN
bun.lockb

Binary file not shown.

170
cli.ts
View file

@ -1,43 +1,70 @@
import type { Prisma } from "@prisma/client";
import chalk from "chalk"; import chalk from "chalk";
import { client } from "~database/datasource"; import { client } from "~database/datasource";
import { createNewLocalUser } from "~database/entities/User"; import { createNewLocalUser } from "~database/entities/User";
import Table from "cli-table";
const args = process.argv; const args = process.argv;
/**
* Make the text have a width of 20 characters, padding with gray dots
* Text can be a Chalk string, in which case formatting codes should not be counted in text length
* @param text The text to align
*/
const alignDots = (text: string, length = 20) => {
// Remove formatting codes
// eslint-disable-next-line no-control-regex
const textLength = text.replace(/\u001b\[\d+m/g, "").length;
const dots = ".".repeat(length - textLength);
return `${text}${chalk.gray(dots)}`;
};
const alignDotsSmall = (text: string, length = 16) => alignDots(text, length);
const help = ` const help = `
${chalk.bold(`Usage: bun cli <command> ${chalk.blue("[...flags]")} [...args]`)} ${chalk.bold(`Usage: bun cli <command> ${chalk.blue("[...flags]")} [...args]`)}
${chalk.bold("Commands:")} ${chalk.bold("Commands:")}
${chalk.blue("help")} ${chalk.gray( ${alignDots(chalk.blue("help"), 24)} Show this help message
"................." ${alignDots(chalk.blue("user"), 24)} Manage users
)} Show this help message ${alignDots(chalk.blue("create"))} Create a new user
${chalk.blue("user")} ${chalk.gray(".................")} Manage users ${alignDotsSmall(chalk.green("username"))} Username of the user
${chalk.blue("create")} ${chalk.gray("...........")} Create a new user ${alignDotsSmall(chalk.green("password"))} Password of the user
${chalk.green("username")} ${chalk.gray( ${alignDotsSmall(chalk.green("email"))} Email of the user
"....." ${alignDotsSmall(
)} Username of the user chalk.yellow("--admin")
${chalk.green("password")} ${chalk.gray(
"....."
)} Password of the user
${chalk.green("email")} ${chalk.gray("........")} Email of the user
${chalk.yellow("--admin")} ${chalk.gray(
"......"
)} Make the user an admin (optional) )} Make the user an admin (optional)
${chalk.bold("Example:")} ${chalk.bgGray( ${chalk.bold("Example:")} ${chalk.bgGray(
`bun cli user create admin password123 admin@gmail.com --admin` `bun cli user create admin password123 admin@gmail.com --admin`
)} )}
${chalk.blue("delete")} ${chalk.gray("...........")} Delete a user ${alignDots(chalk.blue("delete"))} Delete a user
${chalk.green("username")} ${chalk.gray( ${alignDotsSmall(chalk.green("username"))} Username of the user
"....."
)} Username of the user
${chalk.bold("Example:")} ${chalk.bgGray( ${chalk.bold("Example:")} ${chalk.bgGray(
`bun cli user delete admin` `bun cli user delete admin`
)} )}
${chalk.blue("list")} ${chalk.gray(".............")} List all users ${alignDots(chalk.blue("list"))} List all users
${chalk.yellow("--admins")} ${chalk.gray( ${alignDotsSmall(
"....." chalk.yellow("--admins")
)} List only admins (optional) )} List only admins (optional)
${chalk.bold("Example:")} ${chalk.bgGray(`bun cli user list`)} ${chalk.bold("Example:")} ${chalk.bgGray(`bun cli user list`)}
${alignDots(chalk.blue("search"))} Search for a user
${alignDotsSmall(chalk.green("query"))} Query to search for
${alignDotsSmall(
chalk.yellow("--displayname")
)} Search by display name (optional)
${alignDotsSmall(chalk.yellow("--bio"))} Search in bio (optional)
${alignDotsSmall(
chalk.yellow("--local")
)} Search in local users (optional)
${alignDotsSmall(
chalk.yellow("--remote")
)} Search in remote users (optional)
${alignDotsSmall(
chalk.yellow("--email")
)} Search in emails (optional)
${chalk.bold("Example:")} ${chalk.bgGray(
`bun cli user search admin`
)}
`; `;
if (args.length < 3) { if (args.length < 3) {
@ -158,6 +185,107 @@ switch (command) {
} }
break; break;
} }
case "search": {
const argsWithoutFlags = args.filter(
arg => !arg.startsWith("--")
);
const query = argsWithoutFlags[4];
if (!query) {
console.log(`${chalk.red(``)} Missing query`);
process.exit(1);
}
const displayname = args.includes("--displayname");
const bio = args.includes("--bio");
const local = args.includes("--local");
const remote = args.includes("--remote");
const email = args.includes("--email");
const queries: Prisma.UserWhereInput[] = [];
if (displayname) {
queries.push({
displayName: {
contains: query,
mode: "insensitive",
},
});
}
if (bio) {
queries.push({
note: {
contains: query,
mode: "insensitive",
},
});
}
if (local) {
queries.push({
instanceId: null,
});
}
if (remote) {
queries.push({
instanceId: {
not: null,
},
});
}
if (email) {
queries.push({
email: {
contains: query,
mode: "insensitive",
},
});
}
const users = await client.user.findMany({
where: {
AND: queries,
},
include: {
instance: true,
},
});
console.log(
`${chalk.green(``)} Found ${chalk.blue(
users.length
)} users`
);
const table = new Table({
head: [
chalk.white(chalk.bold("Username")),
chalk.white(chalk.bold("Email")),
chalk.white(chalk.bold("Display Name")),
chalk.white(chalk.bold("Admin?")),
chalk.white(chalk.bold("Instance URL")),
],
});
for (const user of users) {
table.push([
chalk.yellow(`@${user.username}`),
chalk.green(user.email),
chalk.blue(user.displayName),
chalk.red(user.isAdmin ? "Yes" : "No"),
chalk.blue(
user.instanceId ? user.instance?.base_url : "Local"
),
]);
}
console.log(table.toString());
break;
}
default: default:
console.log(`Unknown command ${chalk.blue(command)}`); console.log(`Unknown command ${chalk.blue(command)}`);
break; break;

View file

@ -48,6 +48,7 @@
"devDependencies": { "devDependencies": {
"@julr/unocss-preset-forms": "^0.1.0", "@julr/unocss-preset-forms": "^0.1.0",
"@microsoft/eslint-formatter-sarif": "^3.0.0", "@microsoft/eslint-formatter-sarif": "^3.0.0",
"@types/cli-table": "^0.3.4",
"@types/html-to-text": "^9.0.4", "@types/html-to-text": "^9.0.4",
"@types/jsonld": "^1.5.13", "@types/jsonld": "^1.5.13",
"@typescript-eslint/eslint-plugin": "^6.13.1", "@typescript-eslint/eslint-plugin": "^6.13.1",
@ -73,6 +74,7 @@
"blurhash": "^2.0.5", "blurhash": "^2.0.5",
"bullmq": "^4.14.4", "bullmq": "^4.14.4",
"chalk": "^5.3.0", "chalk": "^5.3.0",
"cli-table": "^0.3.11",
"eventemitter3": "^5.0.1", "eventemitter3": "^5.0.1",
"html-to-text": "^9.0.5", "html-to-text": "^9.0.5",
"ip-matching": "^2.1.2", "ip-matching": "^2.1.2",