mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
feat(cli): ✨ Add new CLI commands, move to project root
This commit is contained in:
parent
68f16f9101
commit
fc06b35c09
|
|
@ -1,8 +1,9 @@
|
||||||
|
import { Args, type Command, Flags, type Interfaces } from "@oclif/core";
|
||||||
|
import chalk from "chalk";
|
||||||
import { and, eq, like } from "drizzle-orm";
|
import { and, eq, like } from "drizzle-orm";
|
||||||
import { Users } from "~drizzle/schema";
|
import { Users } from "~drizzle/schema";
|
||||||
import type { User } from "~packages/database-interface/user";
|
import type { User } from "~packages/database-interface/user";
|
||||||
import { BaseCommand } from "./base";
|
import { BaseCommand } from "./base";
|
||||||
import { Args, Flags, type Command, type Interfaces } from "@oclif/core";
|
|
||||||
|
|
||||||
export type FlagsType<T extends typeof Command> = Interfaces.InferredFlags<
|
export type FlagsType<T extends typeof Command> = Interfaces.InferredFlags<
|
||||||
(typeof BaseCommand)["baseFlags"] & T["flags"]
|
(typeof BaseCommand)["baseFlags"] & T["flags"]
|
||||||
|
|
@ -63,6 +64,17 @@ export abstract class UserFinderCommand<
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findUsers(): Promise<User[]> {
|
public async findUsers(): Promise<User[]> {
|
||||||
|
// Check if there are asterisks in the identifier but no pattern flag, warn the user if so
|
||||||
|
if (this.args.identifier.includes("*") && !this.flags.pattern) {
|
||||||
|
this.log(
|
||||||
|
chalk.bold(
|
||||||
|
`${chalk.yellow(
|
||||||
|
"⚠",
|
||||||
|
)} Your identifier has asterisks but the --pattern flag is not set. This will match a literal string. If you want to use wildcards, set the --pattern flag.`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const operator = this.flags.pattern ? like : eq;
|
const operator = this.flags.pattern ? like : eq;
|
||||||
// Replace wildcards with an SQL LIKE pattern
|
// Replace wildcards with an SQL LIKE pattern
|
||||||
const identifier = this.flags.pattern
|
const identifier = this.flags.pattern
|
||||||
94
cli/commands/emoji/add.ts
Normal file
94
cli/commands/emoji/add.ts
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
import { Args } from "@oclif/core";
|
||||||
|
import chalk from "chalk";
|
||||||
|
import { BaseCommand } from "~/cli/base";
|
||||||
|
import { db } from "~drizzle/db";
|
||||||
|
|
||||||
|
export default class EmojiAdd extends BaseCommand<typeof EmojiAdd> {
|
||||||
|
static override args = {
|
||||||
|
shortcode: Args.string({
|
||||||
|
description: "Shortcode of the emoji",
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
file: Args.string({
|
||||||
|
description: "Path to the image file (can be an URL)",
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
static override description = "Adds a new emoji";
|
||||||
|
|
||||||
|
static override examples = ["<%= config.bin %> <%= command.id %>"];
|
||||||
|
|
||||||
|
static override flags = {};
|
||||||
|
|
||||||
|
public async run(): Promise<void> {
|
||||||
|
const { flags, args } = await this.parse(EmojiAdd);
|
||||||
|
|
||||||
|
// Check if emoji already exists
|
||||||
|
const existingEmoji = await db.query.Emojis.findFirst({
|
||||||
|
where: (Emojis, { eq }) => eq(Emojis.shortcode, args.shortcode),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingEmoji) {
|
||||||
|
this.log(
|
||||||
|
`${chalk.red("✗")} Emoji with shortcode ${chalk.red(
|
||||||
|
args.shortcode,
|
||||||
|
)} already exists`,
|
||||||
|
);
|
||||||
|
this.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if (!user) {
|
||||||
|
this.log(
|
||||||
|
`${chalk.red("✗")} Failed to create user ${chalk.red(
|
||||||
|
args.username,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
this.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
!flags.format &&
|
||||||
|
this.log(
|
||||||
|
`${chalk.green("✓")} Created user ${chalk.green(
|
||||||
|
user.getUser().username,
|
||||||
|
)} with id ${chalk.green(user.id)}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.log(
|
||||||
|
formatArray(
|
||||||
|
[user.getUser()],
|
||||||
|
[
|
||||||
|
"id",
|
||||||
|
"username",
|
||||||
|
"displayName",
|
||||||
|
"createdAt",
|
||||||
|
"updatedAt",
|
||||||
|
"isAdmin",
|
||||||
|
],
|
||||||
|
flags.format as "json" | "csv" | undefined,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!flags.format && !flags["set-password"]) {
|
||||||
|
const link = "";
|
||||||
|
|
||||||
|
this.log(
|
||||||
|
flags.format
|
||||||
|
? link
|
||||||
|
: `\nPassword reset link for ${chalk.bold(
|
||||||
|
`@${user.getUser().username}`,
|
||||||
|
)}: ${chalk.underline(chalk.blue(link))}\n`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const qrcode = renderUnicodeCompact(link, {
|
||||||
|
border: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pad all lines of QR code with spaces
|
||||||
|
|
||||||
|
this.log(` ${qrcode.replaceAll("\n", "\n ")}`);
|
||||||
|
} */
|
||||||
|
|
||||||
|
this.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
162
cli/commands/user/create.ts
Normal file
162
cli/commands/user/create.ts
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
import input from "@inquirer/input";
|
||||||
|
import { Args, Flags } from "@oclif/core";
|
||||||
|
import chalk from "chalk";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
import { renderUnicodeCompact } from "uqr";
|
||||||
|
import { BaseCommand } from "~cli/base";
|
||||||
|
import { formatArray } from "~cli/utils/format";
|
||||||
|
import { Users } from "~drizzle/schema";
|
||||||
|
import { User } from "~packages/database-interface/user";
|
||||||
|
|
||||||
|
export default class UserCreate extends BaseCommand<typeof UserCreate> {
|
||||||
|
static override args = {
|
||||||
|
username: Args.string({
|
||||||
|
description: "Username",
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
static override description = "Creates a new user";
|
||||||
|
|
||||||
|
static override examples = [
|
||||||
|
"<%= config.bin %> <%= command.id %> johngastron --email joe@gamer.com",
|
||||||
|
"<%= config.bin %> <%= command.id %> bimbobaggins",
|
||||||
|
];
|
||||||
|
|
||||||
|
static override flags = {
|
||||||
|
format: Flags.string({
|
||||||
|
char: "f",
|
||||||
|
description:
|
||||||
|
"Output format (when set, no password reset link is generated)",
|
||||||
|
options: ["json", "csv"],
|
||||||
|
}),
|
||||||
|
admin: Flags.boolean({
|
||||||
|
char: "a",
|
||||||
|
description: "Admin user",
|
||||||
|
allowNo: true,
|
||||||
|
default: false,
|
||||||
|
}),
|
||||||
|
email: Flags.string({
|
||||||
|
char: "e",
|
||||||
|
description: "Email",
|
||||||
|
}),
|
||||||
|
"verify-email": Flags.boolean({
|
||||||
|
description: "Send email verification",
|
||||||
|
default: true,
|
||||||
|
allowNo: true,
|
||||||
|
}),
|
||||||
|
"set-password": Flags.boolean({
|
||||||
|
description: "Type password instead of getting a reset link",
|
||||||
|
default: false,
|
||||||
|
exclusive: ["format"],
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
public async run(): Promise<void> {
|
||||||
|
const { flags, args } = await this.parse(UserCreate);
|
||||||
|
|
||||||
|
// Check if user already exists
|
||||||
|
const existingUser = await User.fromSql(
|
||||||
|
eq(Users.username, args.username),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (existingUser) {
|
||||||
|
this.log(
|
||||||
|
`${chalk.red("✗")} User ${chalk.red(
|
||||||
|
args.username,
|
||||||
|
)} already exists`,
|
||||||
|
);
|
||||||
|
this.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let password = null;
|
||||||
|
|
||||||
|
if (flags["set-password"]) {
|
||||||
|
const password1 = await input({
|
||||||
|
message: "Please enter the user's password:",
|
||||||
|
// Set whatever the user types to stars
|
||||||
|
transformer: (value) => "*".repeat(value.length),
|
||||||
|
});
|
||||||
|
|
||||||
|
const password2 = await input({
|
||||||
|
message: "Please confirm the user's password:",
|
||||||
|
// Set whatever the user types to stars
|
||||||
|
transformer: (value) => "*".repeat(value.length),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (password1 !== password2) {
|
||||||
|
this.log(
|
||||||
|
`${chalk.red(
|
||||||
|
"✗",
|
||||||
|
)} Passwords do not match. Please try again.`,
|
||||||
|
);
|
||||||
|
this.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
password = password1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add password resets
|
||||||
|
|
||||||
|
const user = await User.fromDataLocal({
|
||||||
|
email: flags.email ?? undefined,
|
||||||
|
password: password ?? undefined,
|
||||||
|
username: args.username,
|
||||||
|
admin: flags.admin,
|
||||||
|
skipPasswordHash: !!password,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
this.log(
|
||||||
|
`${chalk.red("✗")} Failed to create user ${chalk.red(
|
||||||
|
args.username,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
this.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
!flags.format &&
|
||||||
|
this.log(
|
||||||
|
`${chalk.green("✓")} Created user ${chalk.green(
|
||||||
|
user.getUser().username,
|
||||||
|
)} with id ${chalk.green(user.id)}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.log(
|
||||||
|
formatArray(
|
||||||
|
[user.getUser()],
|
||||||
|
[
|
||||||
|
"id",
|
||||||
|
"username",
|
||||||
|
"displayName",
|
||||||
|
"createdAt",
|
||||||
|
"updatedAt",
|
||||||
|
"isAdmin",
|
||||||
|
],
|
||||||
|
flags.format as "json" | "csv" | undefined,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!flags.format && !flags["set-password"]) {
|
||||||
|
const link = "";
|
||||||
|
|
||||||
|
this.log(
|
||||||
|
flags.format
|
||||||
|
? link
|
||||||
|
: `\nPassword reset link for ${chalk.bold(
|
||||||
|
`@${user.getUser().username}`,
|
||||||
|
)}: ${chalk.underline(chalk.blue(link))}\n`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const qrcode = renderUnicodeCompact(link, {
|
||||||
|
border: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pad all lines of QR code with spaces
|
||||||
|
|
||||||
|
this.log(` ${qrcode.replaceAll("\n", "\n ")}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
|
import confirm from "@inquirer/confirm";
|
||||||
import { Flags } from "@oclif/core";
|
import { Flags } from "@oclif/core";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { formatArray } from "~packages/cli/utils/format";
|
|
||||||
import confirm from "@inquirer/confirm";
|
|
||||||
import ora from "ora";
|
import ora from "ora";
|
||||||
import { UserFinderCommand } from "~packages/cli/classes";
|
import { UserFinderCommand } from "~cli/classes";
|
||||||
|
import { formatArray } from "~cli/utils/format";
|
||||||
|
|
||||||
export default class UserDelete extends UserFinderCommand<typeof UserDelete> {
|
export default class UserDelete extends UserFinderCommand<typeof UserDelete> {
|
||||||
static override description = "Deletes users";
|
static override description = "Deletes users";
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { Flags } from "@oclif/core";
|
import { Flags } from "@oclif/core";
|
||||||
import { and, eq, isNotNull, isNull } from "drizzle-orm";
|
import { and, eq, isNotNull, isNull } from "drizzle-orm";
|
||||||
|
import { BaseCommand } from "~cli/base";
|
||||||
|
import { formatArray } from "~cli/utils/format";
|
||||||
import { Users } from "~drizzle/schema";
|
import { Users } from "~drizzle/schema";
|
||||||
import { BaseCommand } from "~packages/cli/base";
|
|
||||||
import { formatArray } from "~packages/cli/utils/format";
|
|
||||||
import { User } from "~packages/database-interface/user";
|
import { User } from "~packages/database-interface/user";
|
||||||
|
|
||||||
export default class UserList extends BaseCommand<typeof UserList> {
|
export default class UserList extends BaseCommand<typeof UserList> {
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
|
import confirm from "@inquirer/confirm";
|
||||||
import { Flags } from "@oclif/core";
|
import { Flags } from "@oclif/core";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { formatArray } from "~packages/cli/utils/format";
|
|
||||||
import confirm from "@inquirer/confirm";
|
|
||||||
import { renderUnicodeCompact } from "uqr";
|
import { renderUnicodeCompact } from "uqr";
|
||||||
import { UserFinderCommand } from "~packages/cli/classes";
|
import { UserFinderCommand } from "~cli/classes";
|
||||||
|
import { formatArray } from "~cli/utils/format";
|
||||||
|
|
||||||
export default class UserReset extends UserFinderCommand<typeof UserReset> {
|
export default class UserReset extends UserFinderCommand<typeof UserReset> {
|
||||||
static override description = "Resets users' passwords";
|
static override description = "Resets users' passwords";
|
||||||
13
cli/index.ts
Normal file
13
cli/index.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import EmojiAdd from "./commands/emoji/add";
|
||||||
|
import UserCreate from "./commands/user/create";
|
||||||
|
import UserDelete from "./commands/user/delete";
|
||||||
|
import UserList from "./commands/user/list";
|
||||||
|
import UserReset from "./commands/user/reset";
|
||||||
|
|
||||||
|
export const commands = {
|
||||||
|
"user list": UserList,
|
||||||
|
"user delete": UserDelete,
|
||||||
|
"user create": UserCreate,
|
||||||
|
"user reset": UserReset,
|
||||||
|
"emoji add": EmojiAdd,
|
||||||
|
};
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { config } from "~/packages/config-manager";
|
|
||||||
import { drizzle } from "drizzle-orm/node-postgres";
|
import { drizzle } from "drizzle-orm/node-postgres";
|
||||||
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
||||||
import { LogLevel, type LogManager, type MultiLogManager } from "log-manager";
|
import { LogLevel, type LogManager, type MultiLogManager } from "log-manager";
|
||||||
import { Client } from "pg";
|
import { Client } from "pg";
|
||||||
|
import { config } from "~/packages/config-manager";
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema";
|
||||||
|
|
||||||
export const client = new Client({
|
export const client = new Client({
|
||||||
|
|
|
||||||
36
package.json
36
package.json
|
|
@ -35,7 +35,7 @@
|
||||||
"build": "bun run build.ts",
|
"build": "bun run build.ts",
|
||||||
"cloc": "cloc . --exclude-dir node_modules,dist,.output,.nuxt,meta,logs,glitch,glitch-dev --exclude-ext sql,log,pem",
|
"cloc": "cloc . --exclude-dir node_modules,dist,.output,.nuxt,meta,logs,glitch,glitch-dev --exclude-ext sql,log,pem",
|
||||||
"wc": "find server database *.ts docs packages types utils drizzle tests -type f -print0 | wc -m --files0-from=-",
|
"wc": "find server database *.ts docs packages types utils drizzle tests -type f -print0 | wc -m --files0-from=-",
|
||||||
"cli": "bun run packages/cli/bin/run.ts",
|
"cli": "bun run cli/bin/run.ts",
|
||||||
"prune": "ts-prune | grep -v server/ | grep -v dist/ | grep -v '(used in module)'"
|
"prune": "ts-prune | grep -v server/ | grep -v dist/ | grep -v '(used in module)'"
|
||||||
},
|
},
|
||||||
"trustedDependencies": [
|
"trustedDependencies": [
|
||||||
|
|
@ -51,6 +51,27 @@
|
||||||
"sharp",
|
"sharp",
|
||||||
"vue-demi"
|
"vue-demi"
|
||||||
],
|
],
|
||||||
|
"oclif": {
|
||||||
|
"bin": "cli",
|
||||||
|
"dirname": "cli",
|
||||||
|
"commands": {
|
||||||
|
"strategy": "explicit",
|
||||||
|
"target": "./cli/index.ts",
|
||||||
|
"identifier": "commands"
|
||||||
|
},
|
||||||
|
"additionalHelpFlags": ["-h"],
|
||||||
|
"additionalVersionFlags": ["-v"],
|
||||||
|
"plugins": ["@oclif/plugin-help"],
|
||||||
|
"description": "CLI to interface with the Lysand project",
|
||||||
|
"topicSeparator": " ",
|
||||||
|
"topics": {
|
||||||
|
"user": {
|
||||||
|
"description": "Manage users"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"theme": "./cli/theme.json",
|
||||||
|
"flexibleTaxonomy": true
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.7.0",
|
"@biomejs/biome": "^1.7.0",
|
||||||
"@types/cli-table": "^0.3.4",
|
"@types/cli-table": "^0.3.4",
|
||||||
|
|
@ -63,12 +84,23 @@
|
||||||
"bun-types": "latest",
|
"bun-types": "latest",
|
||||||
"drizzle-kit": "^0.20.14",
|
"drizzle-kit": "^0.20.14",
|
||||||
"ts-prune": "^0.10.3",
|
"ts-prune": "^0.10.3",
|
||||||
"typescript": "latest"
|
"typescript": "latest",
|
||||||
|
"@types/cli-progress": "^3.11.5",
|
||||||
|
"oclif": "^4.10.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "^5.3.2"
|
"typescript": "^5.3.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@inquirer/confirm": "^3.1.6",
|
||||||
|
"@inquirer/input": "^2.1.6",
|
||||||
|
"@oclif/core": "^3.26.6",
|
||||||
|
"@oclif/plugin-help": "^6.0.21",
|
||||||
|
"@oclif/plugin-plugins": "^5.0.19",
|
||||||
|
"cli-progress": "^3.12.0",
|
||||||
|
"ora": "^8.0.1",
|
||||||
|
"table": "^6.8.2",
|
||||||
|
"uqr": "^0.1.2",
|
||||||
"@hackmd/markdown-it-task-lists": "^2.1.4",
|
"@hackmd/markdown-it-task-lists": "^2.1.4",
|
||||||
"@hono/zod-validator": "^0.2.1",
|
"@hono/zod-validator": "^0.2.1",
|
||||||
"@json2csv/plainjs": "^7.0.6",
|
"@json2csv/plainjs": "^7.0.6",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
/* import { Command } from "@oclif/core";
|
|
||||||
import UserList from "./commands/user/list";
|
|
||||||
import UserDelete from "./commands/user/delete";
|
|
||||||
|
|
||||||
export const commands = {
|
|
||||||
"user list": UserList,
|
|
||||||
"user delete": UserDelete,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
{
|
|
||||||
"name": "cli",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/confirm": "^3.1.6",
|
|
||||||
"@oclif/core": "^3.26.6",
|
|
||||||
"@oclif/plugin-help": "^6.0.21",
|
|
||||||
"@oclif/plugin-plugins": "^5.0.19",
|
|
||||||
"chalk": "^5.3.0",
|
|
||||||
"cli-progress": "^3.12.0",
|
|
||||||
"ora": "^8.0.1",
|
|
||||||
"table": "^6.8.2",
|
|
||||||
"uqr": "^0.1.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/cli-progress": "^3.11.5",
|
|
||||||
"oclif": "^4.10.4"
|
|
||||||
},
|
|
||||||
"oclif": {
|
|
||||||
"bin": "cli",
|
|
||||||
"dirname": "cli",
|
|
||||||
"commands": {
|
|
||||||
"strategy": "pattern",
|
|
||||||
"target": "./commands"
|
|
||||||
},
|
|
||||||
"additionalHelpFlags": ["-h"],
|
|
||||||
"additionalVersionFlags": ["-v"],
|
|
||||||
"plugins": ["@oclif/plugin-help"],
|
|
||||||
"description": "CLI to interface with the Lysand project",
|
|
||||||
"topicSeparator": " ",
|
|
||||||
"topics": {
|
|
||||||
"user": {
|
|
||||||
"description": "Manage users"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"theme": "./theme.json",
|
|
||||||
"flexibleTaxonomy": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -337,8 +337,8 @@ export class User {
|
||||||
static async fromDataLocal(data: {
|
static async fromDataLocal(data: {
|
||||||
username: string;
|
username: string;
|
||||||
display_name?: string;
|
display_name?: string;
|
||||||
password: string;
|
password: string | undefined;
|
||||||
email: string;
|
email: string | undefined;
|
||||||
bio?: string;
|
bio?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
header?: string;
|
header?: string;
|
||||||
|
|
@ -353,7 +353,8 @@ export class User {
|
||||||
.values({
|
.values({
|
||||||
username: data.username,
|
username: data.username,
|
||||||
displayName: data.display_name ?? data.username,
|
displayName: data.display_name ?? data.username,
|
||||||
password: data.skipPasswordHash
|
password:
|
||||||
|
data.skipPasswordHash || !data.password
|
||||||
? data.password
|
? data.password
|
||||||
: await Bun.password.hash(data.password),
|
: await Bun.password.hash(data.password),
|
||||||
email: data.email,
|
email: data.email,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { config } from "~packages/config-manager";
|
|
||||||
import { LogManager, MultiLogManager } from "log-manager";
|
import { LogManager, MultiLogManager } from "log-manager";
|
||||||
|
import { config } from "~packages/config-manager";
|
||||||
|
|
||||||
const noColors = process.env.NO_COLORS === "true";
|
const noColors = process.env.NO_COLORS === "true";
|
||||||
const noFancyDates = process.env.NO_FANCY_DATES === "true";
|
const noFancyDates = process.env.NO_FANCY_DATES === "true";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue