Update .gitignore, add dist directory

This commit is contained in:
2026-07-20 21:43:05 +01:00
parent 9f2db66760
commit 3bbf00cdb0
153 changed files with 6280 additions and 1 deletions
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+37
View File
@@ -0,0 +1,37 @@
import { Command } from "commander";
import chalk from "chalk";
import { select } from "@inquirer/prompts";
import listTables from "./list-tables";
import runSQL from "./run-sql";
export default function () {
return new Command("admin")
.description("View Tables and Data, Run SQL Queries, Etc.")
.action(async () => {
console.log(chalk.bold(chalk.blue("\nBun MariaDB Admin\n")));
try {
while (true) {
const paradigm = await select({
message: "Choose an action:",
choices: [
{ name: "Tables", value: "list_tables" },
{ name: "SQL", value: "run_sql" },
{ name: chalk.dim("✕ Exit"), value: "exit" },
],
});
if (paradigm === "exit")
break;
if (paradigm === "list_tables") {
const result = await listTables();
if (result === "__exit__")
break;
}
if (paradigm === "run_sql")
await runSQL();
}
}
catch (error) {
console.error(error.message);
}
process.exit();
});
}
+3
View File
@@ -0,0 +1,3 @@
type Params = {};
export default function listTables(params?: Params): Promise<"__exit__" | void>;
export {};
+81
View File
@@ -0,0 +1,81 @@
import chalk from "chalk";
import { select } from "@inquirer/prompts";
import { AppData } from "../../data/app-data";
import showEntries from "./show-entries";
import showFields from "./show-fields";
import dbHandler from "../../lib/db-handler";
import MariaDBQuoteGen from "../../lib/schema/mariadb-quote-gen";
export default async function listTables(params) {
const tables = (await dbHandler({
query: `SELECT table_name FROM ${MariaDBQuoteGen(AppData["DbSchemaManagerTableName"])}`,
})).payload;
if (!tables?.length) {
console.log(chalk.yellow("\nNo tables found.\n"));
return;
}
while (true) {
const tableName = await select({
message: "Select a table:",
choices: [
...tables.map((t) => ({
name: t.table_name,
value: t.table_name,
})),
{ name: chalk.dim("← Go Back"), value: "__back__" },
{ name: chalk.dim("✕ Exit"), value: "__exit__" },
],
});
if (tableName === "__back__")
break;
if (tableName === "__exit__")
return "__exit__";
while (true) {
const action = await select({
message: `"${tableName}" — choose an action:`,
choices: [
{ name: "Entries", value: "entries" },
{ name: "Fields", value: "fields" },
{ name: "Schema", value: "schema" },
{ name: chalk.dim("← Go Back"), value: "__back__" },
{ name: chalk.dim("✕ Exit"), value: "__exit__" },
],
});
if (action === "__back__")
break;
if (action === "__exit__")
return "__exit__";
if (action === "entries") {
const result = await showEntries({ tableName });
if (result === "__exit__")
return "__exit__";
}
if (action === "fields") {
const result = await showFields({ tableName });
if (result === "__exit__")
return "__exit__";
}
if (action === "schema") {
const columns = (await dbHandler({
query: `SELECT ORDINAL_POSITION, COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_KEY, EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION`,
values: [tableName],
})).payload;
console.log(`\n${chalk.bold(`Schema for "${tableName}":`)} \n`);
if (columns?.length) {
console.table(columns.map((c) => ({
"#": c.ORDINAL_POSITION,
Name: c.COLUMN_NAME,
Type: c.COLUMN_TYPE,
Nullable: c.IS_NULLABLE,
Default: c.COLUMN_DEFAULT ?? "(none)",
Key: c.COLUMN_KEY || "",
Extra: c.EXTRA || "",
})));
}
else {
console.log(chalk.yellow("No columns found."));
}
console.log();
}
}
}
}
+3
View File
@@ -0,0 +1,3 @@
type Params = {};
export default function runSQL(params?: Params): Promise<void>;
export {};
+25
View File
@@ -0,0 +1,25 @@
import { input } from "@inquirer/prompts";
import chalk from "chalk";
import dbHandler from "../../lib/db-handler";
export default async function runSQL(params) {
const sql = await input({
message: "Enter SQL query:",
validate: (val) => val.trim().length > 0 || "Query cannot be empty",
});
try {
const res = await dbHandler({ query: sql });
if (res.payload?.length) {
console.log(`\n${chalk.bold(`Result (${res.payload.length} row${res.payload.length !== 1 ? "s" : ""}):`)} \n`);
console.table(res.payload);
}
else if (res.success) {
console.log(chalk.green(`\nSuccess! Affected rows: ${res.insert_return?.affected_rows ?? res.count ?? 0}, Last insert ID: ${res.insert_return?.last_insert_id ?? "—"}\n`));
}
else {
console.error(chalk.red(`\nSQL Error: ${res.error || res.msg}\n`));
}
}
catch (error) {
console.error(chalk.red(`\nSQL Error: ${error.message}\n`));
}
}
+5
View File
@@ -0,0 +1,5 @@
type Params = {
tableName: string;
};
export default function showEntries({ tableName }: Params): Promise<"__exit__" | undefined>;
export {};
+91
View File
@@ -0,0 +1,91 @@
import chalk from "chalk";
import { select, input } from "@inquirer/prompts";
import dbHandler from "../../lib/db-handler";
import MariaDBQuoteGen from "../../lib/schema/mariadb-quote-gen";
const LIMIT = 50;
export default async function showEntries({ tableName }) {
let page = 0;
let searchField = null;
let searchTerm = null;
const quotedTable = MariaDBQuoteGen(tableName);
while (true) {
const offset = page * LIMIT;
const rows = searchTerm
? (await dbHandler({
query: `SELECT * FROM ${quotedTable} WHERE ${MariaDBQuoteGen(searchField)} LIKE ? LIMIT ${LIMIT} OFFSET ${offset}`,
values: [`%${searchTerm}%`],
})).payload
: (await dbHandler({
query: `SELECT * FROM ${quotedTable} LIMIT ${LIMIT} OFFSET ${offset}`,
})).payload;
const countRow = searchTerm
? (await dbHandler({
query: `SELECT COUNT(*) as count FROM ${quotedTable} WHERE ${MariaDBQuoteGen(searchField)} LIKE ?`,
values: [`%${searchTerm}%`],
})).payload
: (await dbHandler({
query: `SELECT COUNT(*) as count FROM ${quotedTable}`,
})).payload;
const total = Number(countRow?.[0]?.count || 0);
const searchInfo = searchTerm
? chalk.dim(` · searching "${searchField}" = "${searchTerm}"`)
: "";
if (!rows) {
return;
}
console.log(`\n${chalk.bold(tableName)} — Page ${page + 1}${searchInfo} (${rows.length} of ${total}):\n`);
if (rows.length) {
console.table(rows);
}
else {
console.log(chalk.yellow("No rows found."));
console.log();
}
const choices = [];
if (page > 0)
choices.push({ name: "← Previous Page", value: "prev" });
if (offset + rows.length < total)
choices.push({ name: "Next Page →", value: "next" });
choices.push({ name: "Search by Field", value: "search" });
if (searchTerm)
choices.push({ name: "Clear Search", value: "clear_search" });
choices.push({ name: chalk.dim("← Go Back"), value: "__back__" });
choices.push({ name: chalk.dim("✕ Exit"), value: "__exit__" });
const action = await select({ message: "Navigate:", choices });
if (action === "__back__")
break;
if (action === "__exit__")
return "__exit__";
if (action === "next")
page++;
if (action === "prev")
page--;
if (action === "clear_search") {
searchField = null;
searchTerm = null;
page = 0;
}
if (action === "search") {
const columns = (await dbHandler({
query: `SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION`,
values: [tableName],
})).payload;
if (!columns?.length) {
console.log(chalk.yellow("No columns found for search."));
continue;
}
searchField = await select({
message: "Search by field:",
choices: columns.map((c) => ({
name: c.COLUMN_NAME,
value: c.COLUMN_NAME,
})),
});
searchTerm = await input({
message: `Search term for "${searchField}":`,
validate: (v) => v.trim().length > 0 || "Cannot be empty",
});
page = 0;
}
}
}
+5
View File
@@ -0,0 +1,5 @@
type Params = {
tableName: string;
};
export default function showFields({ tableName, }: Params): Promise<"__exit__" | void>;
export {};
+60
View File
@@ -0,0 +1,60 @@
import chalk from "chalk";
import { select } from "@inquirer/prompts";
import dbHandler from "../../lib/db-handler";
export default async function showFields({ tableName, }) {
const columns = (await dbHandler({
query: `SELECT ORDINAL_POSITION, COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_KEY, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION`,
values: [tableName],
})).payload;
if (!columns?.length) {
console.log(chalk.yellow(`\nNo columns found for "${tableName}".\n`));
return;
}
const indexes = (await dbHandler({
query: `SELECT INDEX_NAME, COLUMN_NAME, NON_UNIQUE, INDEX_TYPE FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? ORDER BY INDEX_NAME, SEQ_IN_INDEX`,
values: [tableName],
})).payload;
const foreignKeys = (await dbHandler({
query: `SELECT CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND REFERENCED_TABLE_NAME IS NOT NULL`,
values: [tableName],
})).payload;
while (true) {
const fieldName = await select({
message: `"${tableName}" — select a field:`,
choices: [
...columns.map((c) => ({
name: c.COLUMN_NAME,
value: c.COLUMN_NAME,
})),
{ name: chalk.dim("← Go Back"), value: "__back__" },
{ name: chalk.dim("✕ Exit"), value: "__exit__" },
],
});
if (fieldName === "__back__")
break;
if (fieldName === "__exit__")
return "__exit__";
const col = columns.find((c) => c.COLUMN_NAME === fieldName);
const colIndexes = indexes?.filter((i) => i.COLUMN_NAME === fieldName) || [];
const fk = foreignKeys?.find((f) => f.COLUMN_NAME === fieldName);
console.log(`\n${chalk.bold(`Field: "${fieldName}"`)}\n`);
console.log(` ${chalk.dim("Table")} ${tableName}`);
console.log(` ${chalk.dim("Column #")} ${col.ORDINAL_POSITION}`);
console.log(` ${chalk.dim("Type")} ${col.COLUMN_TYPE}`);
console.log(` ${chalk.dim("Primary Key")} ${col.COLUMN_KEY === "PRI" ? chalk.green("YES") : "NO"}`);
console.log(` ${chalk.dim("Not Null")} ${col.IS_NULLABLE === "NO" ? chalk.yellow("YES") : "NO"}`);
console.log(` ${chalk.dim("Default")} ${col.COLUMN_DEFAULT ?? chalk.italic("(none)")}`);
console.log(` ${chalk.dim("Extra")} ${col.EXTRA || chalk.italic("(none)")}`);
console.log(` ${chalk.dim("Indexed")} ${colIndexes.length ? chalk.cyan(colIndexes.map((i) => i.INDEX_NAME).join(", ")) : "NO"}`);
if (fk) {
console.log(` ${chalk.dim("Foreign Key")} ${chalk.magenta(`${fk.REFERENCED_TABLE_NAME}(${fk.REFERENCED_COLUMN_NAME})`)}`);
}
else {
console.log(` ${chalk.dim("Foreign Key")} NO`);
}
if (col.COLUMN_COMMENT) {
console.log(` ${chalk.dim("Comment")} ${col.COLUMN_COMMENT}`);
}
console.log();
}
}
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+33
View File
@@ -0,0 +1,33 @@
import { Command } from "commander";
import path from "path";
import fs from "fs";
import grabDBDir from "../utils/grab-db-dir";
import grabDBBackupFileName from "../utils/grab-db-backup-file-name";
import chalk from "chalk";
import trimBackups from "../utils/trim-backups";
import { dumpDatabase } from "../utils/mariadb-dump-restore";
export default function () {
return new Command("backup")
.description("Backup MariaDB database (SQL dump)")
.action(async () => {
console.log(`Backing up database ...`);
const config = global.CONFIG;
const { backup_dir } = grabDBDir({ config });
if (!fs.existsSync(backup_dir)) {
fs.mkdirSync(backup_dir, { recursive: true });
}
const backup_file_name = grabDBBackupFileName({ config });
const backup_path = path.join(backup_dir, backup_file_name);
try {
const sql = await dumpDatabase(config);
fs.writeFileSync(backup_path, sql, "utf-8");
trimBackups({ config });
console.log(`${chalk.bold(chalk.green(`DB Backup Success!`))}${backup_path}`);
process.exit(0);
}
catch (error) {
console.error(chalk.red(`Backup ERROR => ${error.message}`));
process.exit(1);
}
});
}
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+62
View File
@@ -0,0 +1,62 @@
import { Command } from "commander";
import path from "path";
import fs from "fs";
import chalk from "chalk";
import grabDBDir from "../utils/grab-db-dir";
import { AppData } from "../data/app-data";
import { dumpDatabase } from "../utils/mariadb-dump-restore";
import { writeExportArchive } from "../utils/export-archive";
import trimExports from "../utils/trim-exports";
function defaultExportFileName(dbName, format) {
return `${dbName}-${Date.now()}.${format}`;
}
export default function () {
return new Command("export")
.description("Export database SQL dump + schema.ts into a portable archive")
.option("-o, --output <path>", "Output archive path (.tar.gz or .zip). Defaults to db exports dir")
.option("-f, --format <format>", "Archive format when --output is omitted: tar.gz | zip", "tar.gz")
.action(async (opts) => {
console.log(`Exporting database ...`);
const config = global.CONFIG;
const { db_dir, export_dir } = grabDBDir({ config });
if (!fs.existsSync(export_dir)) {
fs.mkdirSync(export_dir, { recursive: true });
}
const schemaPath = path.join(db_dir, AppData.DbSchemaFileName);
if (!fs.existsSync(schemaPath)) {
console.error(chalk.red(`Schema file not found: ${schemaPath}`));
process.exit(1);
}
const formatRaw = String(opts.format || "tar.gz").toLowerCase();
const format = formatRaw === "zip" ? "zip" : "tar.gz";
let outPath;
if (opts.output) {
outPath = path.resolve(opts.output);
const parent = path.dirname(outPath);
if (!fs.existsSync(parent)) {
fs.mkdirSync(parent, { recursive: true });
}
}
else {
outPath = path.join(export_dir, defaultExportFileName(config.db_name, format));
}
try {
const sql = await dumpDatabase(config);
const schemaTs = fs.readFileSync(schemaPath, "utf-8");
await writeExportArchive({
contents: { sql, schemaTs },
outPath,
});
if (path.dirname(outPath) === export_dir) {
trimExports({ config });
}
console.log(`${chalk.bold(chalk.green(`DB Export Success!`))}${outPath}`);
console.log(chalk.dim(`Contains: dump.sql + ${AppData.DbSchemaFileName}`));
process.exit(0);
}
catch (error) {
console.error(chalk.red(`Export ERROR => ${error.message}`));
process.exit(1);
}
});
}
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+86
View File
@@ -0,0 +1,86 @@
import { Command } from "commander";
import path from "path";
import fs from "fs";
import chalk from "chalk";
import { select } from "@inquirer/prompts";
import grabDBDir from "../utils/grab-db-dir";
import grabSortedExports from "../utils/grab-sorted-exports";
import grabBackupData from "../utils/grab-backup-data";
import { AppData } from "../data/app-data";
import { restoreDatabase } from "../utils/mariadb-dump-restore";
import { isArchivePath, isSqlPath, readExportArchive, } from "../utils/export-archive";
function formatChoice(name, index) {
const { backup_date } = grabBackupData({ backup_name: name });
const time = Number.isNaN(backup_date.getTime())
? "unknown date"
: `${backup_date.toDateString()} ${backup_date.getHours()}:${backup_date.getMinutes()}:${backup_date.getSeconds().toString().padStart(2, "0")}`;
return `#${index + 1}: ${name} (${time})`;
}
export default function () {
return new Command("import")
.description("Import an SQL dump, or a full export archive (SQL + schema.ts)")
.argument("[file]", "Path to .sql file or export archive (.tar.gz / .tar / .zip)")
.option("--sql-only", "When importing an archive, restore SQL only (skip writing schema.ts)")
.option("--schema-only", "When importing an archive, write schema.ts only (skip SQL restore)")
.action(async (fileArg, opts) => {
console.log(`Importing database ...`);
const config = global.CONFIG;
const { db_dir, export_dir } = grabDBDir({ config });
try {
let filePath = fileArg ? path.resolve(fileArg) : "";
if (!filePath) {
const candidates = grabSortedExports({ config }).filter((b) => isArchivePath(b));
if (!candidates[0]) {
console.error(`No export archives found in \`${export_dir}\`. Use \`export\`, or pass a file path.`);
process.exit(1);
}
const selected = await select({
message: "Select an export to import:",
choices: candidates.map((b, i) => ({
name: formatChoice(b, i),
value: b,
})),
});
filePath = path.join(export_dir, selected);
}
if (!fs.existsSync(filePath)) {
console.error(chalk.red(`File not found: ${filePath}`));
process.exit(1);
}
if (isSqlPath(filePath)) {
if (opts.schemaOnly) {
console.error(chalk.red(`--schema-only requires an export archive, not a plain .sql file.`));
process.exit(1);
}
const sql = fs.readFileSync(filePath, "utf-8");
await restoreDatabase(config, sql);
console.log(`${chalk.bold(chalk.green(`DB Import Success!`))}${filePath}`);
process.exit(0);
}
if (!isArchivePath(filePath)) {
console.error(chalk.red(`Unsupported file type: ${filePath}. Use .sql, .tar.gz, .tar, or .zip.`));
process.exit(1);
}
if (opts.sqlOnly && opts.schemaOnly) {
console.error(chalk.red(`Cannot combine --sql-only and --schema-only.`));
process.exit(1);
}
const { sql, schemaTs } = await readExportArchive(filePath);
if (!opts.schemaOnly) {
await restoreDatabase(config, sql);
console.log(chalk.green(`SQL restored from archive`));
}
if (!opts.sqlOnly) {
const schemaPath = path.join(db_dir, AppData.DbSchemaFileName);
fs.writeFileSync(schemaPath, schemaTs, "utf-8");
console.log(chalk.green(`Schema written → ${schemaPath}`));
}
console.log(`${chalk.bold(chalk.green(`DB Import Success!`))}${filePath}`);
process.exit(0);
}
catch (error) {
console.error(chalk.red(`Import ERROR => ${error.message}`));
process.exit(1);
}
});
}
+2
View File
@@ -0,0 +1,2 @@
#!/usr/bin/env bun
export {};
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env bun
import { program } from "commander";
import schema from "./schema";
import typedef from "./typedef";
import backup from "./backup";
import restore from "./restore";
import exportCmd from "./export";
import importCmd from "./import";
import admin from "./admin";
import init from "../functions/init";
init();
/**
* # Describe Program
*/
program
.name(`bun-mariadb`)
.description(`MariaDB manager for Bun`)
.version(`1.0.0`);
/**
* # Declare Commands
*/
program.addCommand(schema());
program.addCommand(typedef());
program.addCommand(backup());
program.addCommand(restore());
program.addCommand(exportCmd());
program.addCommand(importCmd());
program.addCommand(admin());
/**
* # Handle Unavailable Commands
*/
program.on("command:*", () => {
console.error("Invalid command: %s\nSee --help for a list of available commands.", program.args.join(" "));
process.exit(1);
});
/**
* # Parse Arguments
*/
program.parse(Bun.argv);
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+50
View File
@@ -0,0 +1,50 @@
import { Command } from "commander";
import grabDBDir from "../utils/grab-db-dir";
import fs from "fs";
import chalk from "chalk";
import grabSortedBackups from "../utils/grab-sorted-backups";
import { select } from "@inquirer/prompts";
import grabBackupData from "../utils/grab-backup-data";
import path from "path";
import { restoreDatabase } from "../utils/mariadb-dump-restore";
export default function () {
return new Command("restore")
.description("Restore MariaDB database from an SQL dump")
.action(async () => {
console.log(`Restoring database ...`);
const config = global.CONFIG;
const { backup_dir } = grabDBDir({ config });
const backups = grabSortedBackups({ config }).filter((b) => b.endsWith(".sql"));
if (!backups?.[0]) {
console.error(`No SQL backups to restore. Use the \`backup\` command to create a backup.`);
process.exit(1);
}
try {
const selected_backup = await select({
message: "Select a backup:",
choices: backups.map((b, i) => {
const { backup_date } = grabBackupData({
backup_name: b,
});
return {
name: `Backup #${i + 1}: ${backup_date.toDateString()} ${backup_date.getHours()}:${backup_date.getMinutes()}:${backup_date.getSeconds().toString().padStart(2, "0")}`,
value: b,
};
}),
});
const backup_path = path.join(backup_dir, selected_backup);
if (!fs.existsSync(backup_path)) {
console.error(`Backup file not found: ${backup_path}`);
process.exit(1);
}
const sql = fs.readFileSync(backup_path, "utf-8");
await restoreDatabase(config, sql);
console.log(`${chalk.bold(chalk.green(`DB Restore Success!`))}${selected_backup}`);
process.exit(0);
}
catch (error) {
console.error(`Backup Restore ERROR => ${error.message}`);
process.exit(1);
}
});
}
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+44
View File
@@ -0,0 +1,44 @@
import { Command } from "commander";
import grabDirNames from "../data/grab-dir-names";
import path from "path";
import dbSchemaToTypeDef from "../lib/mariadb/schema-to-typedef";
import appendDefaultFieldsToDbSchema from "../utils/append-default-fields-to-db-schema";
import chalk from "chalk";
import { writeLiveSchema } from "../functions/live-schema";
import createDBSchema from "../lib/schema/create-db-schema";
export default function () {
return new Command("schema")
.description("Build DB From Schema")
.option("-t, --typedef", "Generate typescript type definitions")
.action(async (opts) => {
console.log(`Starting process ...`);
const config = global.CONFIG;
const dbSchema = global.DB_SCHEMA;
const { ROOT_DIR } = grabDirNames();
try {
const isTypeDef = Boolean(opts.typedef || opts.t);
const finaldbSchema = appendDefaultFieldsToDbSchema({
dbSchema,
});
await createDBSchema({
db_schema: finaldbSchema,
config,
});
if (isTypeDef && config.typedef_file_path) {
const out_file = path.resolve(ROOT_DIR, config.typedef_file_path);
dbSchemaToTypeDef({
dbSchema: finaldbSchema,
dst_file: out_file,
config,
});
}
writeLiveSchema({ schema: finaldbSchema });
console.log(`${chalk.bold(chalk.green(`DB Schema setup success!`))}`);
process.exit(0);
}
catch (error) {
console.error(error);
process.exit(1);
}
});
}
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+29
View File
@@ -0,0 +1,29 @@
import { Command } from "commander";
import dbSchemaToTypeDef from "../lib/mariadb/schema-to-typedef";
import path from "path";
import grabDirNames from "../data/grab-dir-names";
import appendDefaultFieldsToDbSchema from "../utils/append-default-fields-to-db-schema";
import chalk from "chalk";
export default function () {
return new Command("typedef")
.description("Generate TypeScript type definitions from the schema")
.action(async () => {
console.log(`Creating Type Definition From DB Schema ...`);
const config = global.CONFIG;
const dbSchema = global.DB_SCHEMA;
const { ROOT_DIR } = grabDirNames();
const finaldbSchema = appendDefaultFieldsToDbSchema({ dbSchema });
if (!config.typedef_file_path) {
console.error(`\`typedef_file_path\` is required in bun-mariadb.config.ts to generate types.`);
process.exit(1);
}
const out_file = path.resolve(ROOT_DIR, config.typedef_file_path);
dbSchemaToTypeDef({
dbSchema: finaldbSchema,
dst_file: out_file,
config,
});
console.log(`${chalk.bold(chalk.green(`Typedef gen success!`))}`);
process.exit(0);
});
}