UNPKG

@npio/cli

Version:

A free visual website editor, powered with your own SolidJS components.

177 lines (157 loc) 4.33 kB
import { cancel, group, intro, log, outro, password, spinner, text, } from "@clack/prompts"; import { hashPassword, useDatabase } from "nitropage/server"; import c from "picocolors"; import type sade from "sade"; const confirmedPassword = async function (): Promise<string> { const result = await group( { pw: () => password({ message: "What is the password?", validate(value) { if (!value) return "Password is required!"; }, }), pw2: () => password({ message: "Please confirm the password", }), }, { onCancel(opts) { cancel("Cancelled."); process.exit(); }, }, ); if (result.pw !== result.pw2) { log.error("The passwords did not match!"); return await confirmedPassword(); } return result.pw; }; export const userCommands = function (prog: sade.Sade) { prog .command("user list") .describe("List up the registered users") .action(async function () { const client = useDatabase(); const users = await client.nitroUser.findMany({ select: { id: true, email: true, username: true, admin: true, }, }); for (const { id, email, username, admin } of users) { console.log({ id, email, username, admin, }); } }); prog .command("user set <id>") .describe("Update fields of the specified user") .option("--password, -p", "Provide new password") .action( async (id: string, { password }: { password: string | boolean }) => { intro("Update user"); const data: { password?: string } = {}; if (password) { if (typeof password === "boolean") { password = await confirmedPassword(); } data.password = await hashPassword(password); } const s = spinner(); s.start("Updating"); if (Object.keys(data).length === 0) { s.stop("Nothing to update."); outro("Done."); return; } const client = useDatabase(); const result = await client.nitroUser.updateMany({ where: { id, }, data, }); s.stop("Database query executed."); if (!result.count) { log.warn(`No user with id ${c.bold(id)} found.`); outro("Done."); process.exit(1); } outro(`Updated user ${c.bold(id)}.`); }, ); prog .command("user add") .describe("Create a new user") .action(async () => { const client = useDatabase(); const users = await client.nitroUser.findMany({ select: { username: true, email: true, }, }); const existingMails = users.map((user) => user.email); const existingUsernames = users.map((user) => user.username); intro("Let's create a new user!"); const result = await group( { username: () => text({ message: "What is the username?", validate(value) { if (value.length === 0) return "Username is required!"; if (existingUsernames.includes(value)) return "Username already exists!"; }, }), email: () => text({ message: "What is the email address?", validate(value) { if (value.length === 0) return "Email address is required!"; if (!value.includes("@")) return "Email address is incorrect!"; if (existingMails.includes(value)) return "Email address already exists!"; }, }), }, { onCancel(opts) { cancel("Creation cancelled."); process.exit(); }, }, ); const { username, email } = result; const pw = await confirmedPassword(); await client.nitroUser.create({ data: { email, username, password: await hashPassword(pw), admin: true, }, }); outro(`User ${c.bold(username)} <${email}> created.`); }); };