Major version update. Major bugfixes. Security vulnerabilites fixed
This commit is contained in:
Vendored
+1
-8
@@ -1,20 +1,13 @@
|
||||
import { Command } from "commander";
|
||||
import init from "../../functions/init";
|
||||
import grabDBDir from "../../utils/grab-db-dir";
|
||||
import chalk from "chalk";
|
||||
import { select } from "@inquirer/prompts";
|
||||
import { Database } from "bun:sqlite";
|
||||
import listTables from "./list-tables";
|
||||
import runSQL from "./run-sql";
|
||||
import * as sqliteVec from "sqlite-vec";
|
||||
export default function () {
|
||||
return new Command("admin")
|
||||
.description("View Tables and Data, Run SQL Queries, Etc.")
|
||||
.action(async () => {
|
||||
const { config } = await init();
|
||||
const { db_file_path } = grabDBDir({ config });
|
||||
const db = new Database(db_file_path);
|
||||
sqliteVec.load(db);
|
||||
const db = global.SQLITE_CLIENT;
|
||||
console.log(chalk.bold(chalk.blue("\nBun SQLite Admin\n")));
|
||||
try {
|
||||
while (true) {
|
||||
|
||||
Vendored
+7
-5
@@ -1,20 +1,22 @@
|
||||
import { Command } from "commander";
|
||||
import init from "../functions/init";
|
||||
import path from "path";
|
||||
import grabDBDir from "../utils/grab-db-dir";
|
||||
import fs from "fs";
|
||||
import grabDBBackupFileName from "../utils/grab-db-backup-file-name";
|
||||
import chalk from "chalk";
|
||||
import trimBackups from "../utils/trim-backups";
|
||||
import snapshotDb from "../utils/snapshot-db";
|
||||
export default function () {
|
||||
return new Command("backup")
|
||||
.description("Backup Database")
|
||||
.action(async (opts) => {
|
||||
console.log(`Backing up database ...`);
|
||||
const { config } = await init();
|
||||
const { backup_dir, db_file_path } = grabDBDir({ config });
|
||||
const config = global.CONFIG;
|
||||
const { backup_dir } = grabDBDir({ config });
|
||||
const new_db_file_name = grabDBBackupFileName({ config });
|
||||
fs.cpSync(db_file_path, path.join(backup_dir, new_db_file_name));
|
||||
snapshotDb({
|
||||
db: global.SQLITE_CLIENT,
|
||||
dst: path.join(backup_dir, new_db_file_name),
|
||||
});
|
||||
trimBackups({ config });
|
||||
console.log(`${chalk.bold(chalk.green(`DB Backup Success!`))}`);
|
||||
process.exit();
|
||||
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
Vendored
+70
@@ -0,0 +1,70 @@
|
||||
import { Command } from "commander";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import chalk from "chalk";
|
||||
import grabDBDir from "../utils/grab-db-dir";
|
||||
import grabDirNames from "../data/grab-dir-names";
|
||||
import snapshotDb from "../utils/snapshot-db";
|
||||
import { writeExportArchive } from "../utils/export-archive";
|
||||
import trimExports from "../utils/trim-exports";
|
||||
import { AppData } from "../data/app-data";
|
||||
function defaultExportFileName(dbName, format) {
|
||||
return `${dbName}-${Date.now()}.${format}`;
|
||||
}
|
||||
export default function () {
|
||||
return new Command("export")
|
||||
.description("Export database file + schema 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 { export_dir } = grabDBDir({ config });
|
||||
const { BUN_SQLITE_TEMP_DIR } = grabDirNames();
|
||||
if (!fs.existsSync(export_dir)) {
|
||||
fs.mkdirSync(export_dir, { recursive: true });
|
||||
}
|
||||
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);
|
||||
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
||||
}
|
||||
else {
|
||||
outPath = path.join(export_dir, defaultExportFileName(config.db_name, format));
|
||||
}
|
||||
const snapshot_path = path.join(BUN_SQLITE_TEMP_DIR, `export-${Date.now()}.db`);
|
||||
/** Remove the temp database file before exiting */
|
||||
const exit = (code) => {
|
||||
fs.rmSync(snapshot_path, { force: true });
|
||||
process.exit(code);
|
||||
};
|
||||
try {
|
||||
snapshotDb({ db: global.SQLITE_CLIENT, dst: snapshot_path });
|
||||
/**
|
||||
* The schema is always stored as `schema.<ext>` so `import`
|
||||
* can find it, whatever `db_schema_file_name` is.
|
||||
*/
|
||||
const schemaFileName = `${AppData.DbSchemaFileName}${path.extname(global.SCHEMA_FILE_PATH)}`;
|
||||
await writeExportArchive({
|
||||
contents: {
|
||||
db: new Uint8Array(fs.readFileSync(snapshot_path)),
|
||||
schema: fs.readFileSync(global.SCHEMA_FILE_PATH, "utf-8"),
|
||||
schemaFileName,
|
||||
},
|
||||
outPath,
|
||||
});
|
||||
if (path.dirname(outPath) === export_dir) {
|
||||
trimExports({ config });
|
||||
}
|
||||
console.log(`${chalk.bold(chalk.green(`DB Export Success!`))} → ${outPath}`);
|
||||
console.log(chalk.dim(`Contains: database.sqlite + ${schemaFileName}`));
|
||||
exit(0);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(chalk.red(`Export ERROR => ${error.message}`));
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
Vendored
+187
@@ -0,0 +1,187 @@
|
||||
import { Command } from "commander";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import chalk from "chalk";
|
||||
import { Database } from "bun:sqlite";
|
||||
import * as sqliteVec from "sqlite-vec";
|
||||
import { confirm, select } from "@inquirer/prompts";
|
||||
import grabDBDir from "../utils/grab-db-dir";
|
||||
import grabDirNames from "../data/grab-dir-names";
|
||||
import grabSortedExports from "../utils/grab-sorted-exports";
|
||||
import grabBackupData from "../utils/grab-backup-data";
|
||||
import grabDBBackupFileName from "../utils/grab-db-backup-file-name";
|
||||
import snapshotDb from "../utils/snapshot-db";
|
||||
import trimBackups from "../utils/trim-backups";
|
||||
import replaceDbFile from "../utils/replace-db-file";
|
||||
import { isArchivePath, isSQLiteFile, isSqlPath, readExportArchive, } from "../utils/export-archive";
|
||||
import { resolveDataFile } from "../utils/resolve-and-load-data-file";
|
||||
import { AppData } from "../data/app-data";
|
||||
function formatChoice(name, index) {
|
||||
const { backup_date } = grabBackupData({
|
||||
backup_name: name.replace(/\.(tar\.gz|tgz|tar|zip)$/i, ""),
|
||||
});
|
||||
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})`;
|
||||
}
|
||||
/**
|
||||
* # Replace the live database with the database file at `src`
|
||||
* @description The current database is backed up first.
|
||||
*/
|
||||
function swapDatabase(src) {
|
||||
const config = global.CONFIG;
|
||||
const { backup_dir, db_file_path } = grabDBDir({ config });
|
||||
const backup_path = path.join(backup_dir, grabDBBackupFileName({ config }));
|
||||
snapshotDb({ db: global.SQLITE_CLIENT, dst: backup_path });
|
||||
trimBackups({ config });
|
||||
console.log(chalk.dim(`Backed up current database → ${backup_path}`));
|
||||
global.SQLITE_CLIENT.close();
|
||||
replaceDbFile({ src, db_file_path });
|
||||
}
|
||||
/**
|
||||
* # Build a database file from an SQL script
|
||||
*/
|
||||
function buildDbFromSql({ sql, dst }) {
|
||||
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
||||
fs.rmSync(dst, { force: true });
|
||||
const db = new Database(dst, { create: true });
|
||||
try {
|
||||
sqliteVec.load(db);
|
||||
db.run(sql);
|
||||
}
|
||||
finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* # Write the schema file from an archive into the project
|
||||
*/
|
||||
function writeSchema({ schema, schemaFileName, }) {
|
||||
const config = global.CONFIG;
|
||||
const { db_dir } = grabDBDir({ config });
|
||||
if (config.db_schema_file_name) {
|
||||
const schemaPath = path.join(db_dir, config.db_schema_file_name);
|
||||
if (path.extname(schemaPath) !== path.extname(schemaFileName)) {
|
||||
throw new Error(`Archive schema is \`${schemaFileName}\` but \`db_schema_file_name\` is \`${config.db_schema_file_name}\`. Use --sql-only, or change \`db_schema_file_name\`.`);
|
||||
}
|
||||
fs.writeFileSync(schemaPath, schema, "utf-8");
|
||||
console.log(chalk.green(`Schema written → ${schemaPath}`));
|
||||
return;
|
||||
}
|
||||
const existing = resolveDataFile(db_dir, AppData.DbSchemaFileName);
|
||||
const schemaPath = path.join(db_dir, schemaFileName);
|
||||
// Remove a differently-named schema so only one format remains
|
||||
if (existing && path.resolve(existing.path) !== path.resolve(schemaPath)) {
|
||||
fs.unlinkSync(existing.path);
|
||||
console.log(chalk.dim(`Removed previous schema file: ${existing.basename}`));
|
||||
}
|
||||
fs.writeFileSync(schemaPath, schema, "utf-8");
|
||||
console.log(chalk.green(`Schema written → ${schemaPath}`));
|
||||
}
|
||||
export default function () {
|
||||
return new Command("import")
|
||||
.description("Import a SQLite database file, an SQL script, or a full export archive (database + schema)")
|
||||
.argument("[file]", "Path to a SQLite file, .sql file, or export archive (.tar.gz / .tar / .zip)")
|
||||
.option("--sql-only", "When importing an archive, restore the database only (skip writing schema)")
|
||||
.option("--schema-only", "When importing an archive, write schema only (skip database restore)")
|
||||
.option("-y, --yes", "Do not ask for confirmation before writing an executable (.ts/.js) schema from the archive")
|
||||
.action(async (fileArg, opts) => {
|
||||
console.log(`Importing database ...`);
|
||||
const config = global.CONFIG;
|
||||
const { db_dir, export_dir } = grabDBDir({ config });
|
||||
const { BUN_SQLITE_TEMP_DIR } = grabDirNames();
|
||||
const temp_db_path = path.join(BUN_SQLITE_TEMP_DIR, `import-${Date.now()}.db`);
|
||||
/** Remove the temp database file before exiting */
|
||||
const exit = (code) => {
|
||||
fs.rmSync(temp_db_path, { force: true });
|
||||
process.exit(code);
|
||||
};
|
||||
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.`);
|
||||
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}`));
|
||||
exit(1);
|
||||
}
|
||||
if (opts.sqlOnly && opts.schemaOnly) {
|
||||
console.error(chalk.red(`Cannot combine --sql-only and --schema-only.`));
|
||||
exit(1);
|
||||
}
|
||||
if (!isArchivePath(filePath)) {
|
||||
if (opts.schemaOnly) {
|
||||
console.error(chalk.red(`--schema-only requires an export archive.`));
|
||||
exit(1);
|
||||
}
|
||||
if (isSqlPath(filePath)) {
|
||||
buildDbFromSql({
|
||||
sql: fs.readFileSync(filePath, "utf-8"),
|
||||
dst: temp_db_path,
|
||||
});
|
||||
swapDatabase(temp_db_path);
|
||||
}
|
||||
else if (isSQLiteFile(new Uint8Array(fs.readFileSync(filePath)))) {
|
||||
swapDatabase(filePath);
|
||||
}
|
||||
else {
|
||||
console.error(chalk.red(`Unsupported file: ${filePath}. Use a SQLite database file, .sql, .tar.gz, .tar, or .zip.`));
|
||||
exit(1);
|
||||
}
|
||||
console.log(`${chalk.bold(chalk.green(`DB Import Success!`))} ← ${filePath}`);
|
||||
exit(0);
|
||||
}
|
||||
const { db, schema, schemaFileName } = await readExportArchive(filePath);
|
||||
/**
|
||||
* A .ts/.js schema is executed (require) on the next run.
|
||||
* Confirm before writing code from an archive into the project.
|
||||
*/
|
||||
const isExecutableSchema = /\.(ts|js)$/i.test(schemaFileName);
|
||||
if (!opts.sqlOnly && isExecutableSchema && !opts.yes) {
|
||||
if (!process.stdin.isTTY) {
|
||||
console.error(chalk.red(`Archive contains an executable schema (${schemaFileName}). Re-run with --yes to accept it, or --sql-only to skip it.`));
|
||||
exit(1);
|
||||
}
|
||||
console.log(chalk.yellow(`\nThis archive contains an executable schema file (${schemaFileName}).\nIt will run as code the next time bun-sqlite or your app loads it.\nOnly continue if you trust the source of this archive.\n`));
|
||||
const proceed = await confirm({
|
||||
message: `Write ${schemaFileName} into ${db_dir}?`,
|
||||
default: false,
|
||||
});
|
||||
if (!proceed) {
|
||||
console.log(chalk.dim(`Import cancelled.`));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (!opts.sqlOnly) {
|
||||
writeSchema({ schema, schemaFileName });
|
||||
}
|
||||
if (!opts.schemaOnly) {
|
||||
fs.mkdirSync(path.dirname(temp_db_path), {
|
||||
recursive: true,
|
||||
});
|
||||
fs.writeFileSync(temp_db_path, db);
|
||||
swapDatabase(temp_db_path);
|
||||
console.log(chalk.green(`Database restored from archive`));
|
||||
}
|
||||
console.log(`${chalk.bold(chalk.green(`DB Import Success!`))} ← ${filePath}`);
|
||||
exit(0);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(chalk.red(`Import ERROR => ${error.message}`));
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
Vendored
-4
@@ -1,6 +1,2 @@
|
||||
#!/usr/bin/env bun
|
||||
/**
|
||||
* # Declare Global Variables
|
||||
*/
|
||||
declare global { }
|
||||
export {};
|
||||
|
||||
+20
-2
@@ -4,14 +4,27 @@ 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";
|
||||
import { readFileSync } from "fs";
|
||||
try {
|
||||
init();
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`Initialization ERROR => ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
/** Resolves to the package root from both src/commands and dist/commands */
|
||||
const { version } = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf-8"));
|
||||
/**
|
||||
* # Describe Program
|
||||
*/
|
||||
program
|
||||
.name(`bun-sqlite`)
|
||||
.description(`SQLite manager for Bun`)
|
||||
.version(`1.0.0`);
|
||||
.version(version);
|
||||
/**
|
||||
* # Declare Commands
|
||||
*/
|
||||
@@ -19,6 +32,8 @@ program.addCommand(schema());
|
||||
program.addCommand(typedef());
|
||||
program.addCommand(backup());
|
||||
program.addCommand(restore());
|
||||
program.addCommand(exportCmd());
|
||||
program.addCommand(importCmd());
|
||||
program.addCommand(admin());
|
||||
/**
|
||||
* # Handle Unavailable Commands
|
||||
@@ -30,4 +45,7 @@ program.on("command:*", () => {
|
||||
/**
|
||||
* # Parse Arguments
|
||||
*/
|
||||
program.parse(Bun.argv);
|
||||
program.parseAsync(Bun.argv).catch((error) => {
|
||||
console.error(`ERROR => ${error?.message || error}`);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
Vendored
+8
-5
@@ -1,7 +1,6 @@
|
||||
import { Command } from "commander";
|
||||
import init from "../functions/init";
|
||||
import grabDBDir from "../utils/grab-db-dir";
|
||||
import fs from "fs";
|
||||
import replaceDbFile from "../utils/replace-db-file";
|
||||
import chalk from "chalk";
|
||||
import grabSortedBackups from "../utils/grab-sorted-backups";
|
||||
import { select } from "@inquirer/prompts";
|
||||
@@ -12,7 +11,7 @@ export default function () {
|
||||
.description("Restore Database")
|
||||
.action(async (opts) => {
|
||||
console.log(`Restoring up database ...`);
|
||||
const { config } = await init();
|
||||
const config = global.CONFIG;
|
||||
const { backup_dir, db_file_path } = grabDBDir({ config });
|
||||
const backups = grabSortedBackups({ config });
|
||||
if (!backups?.[0]) {
|
||||
@@ -32,13 +31,17 @@ export default function () {
|
||||
};
|
||||
}),
|
||||
});
|
||||
fs.cpSync(path.join(backup_dir, selected_backup), db_file_path);
|
||||
global.SQLITE_CLIENT.close();
|
||||
replaceDbFile({
|
||||
src: path.join(backup_dir, selected_backup),
|
||||
db_file_path,
|
||||
});
|
||||
console.log(`${chalk.bold(chalk.green(`DB Restore Success!`))}`);
|
||||
process.exit();
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`Backup Restore ERROR => ${error.message}`);
|
||||
process.exit();
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Vendored
+78
-16
@@ -1,38 +1,96 @@
|
||||
import { Command } from "commander";
|
||||
import { SQLiteSchemaManager } from "../lib/sqlite/db-schema-manager";
|
||||
import init from "../functions/init";
|
||||
import createDBSchema from "../lib/schema/create-db-schema";
|
||||
import grabDirNames from "../data/grab-dir-names";
|
||||
import path from "path";
|
||||
import dbSchemaToTypeDef from "../lib/sqlite/schema-to-typedef";
|
||||
import _ from "lodash";
|
||||
import appendDefaultFieldsToDbSchema from "../utils/append-default-fields-to-db-schema";
|
||||
import chalk from "chalk";
|
||||
import { writeLiveSchema } from "../functions/live-schema";
|
||||
import grabDBDir from "../utils/grab-db-dir";
|
||||
import { cpSync } from "fs";
|
||||
import snapshotDb from "../utils/snapshot-db";
|
||||
import replaceDbFile from "../utils/replace-db-file";
|
||||
import { confirm } from "@inquirer/prompts";
|
||||
export default function () {
|
||||
return new Command("schema")
|
||||
.description("Build DB From Schema")
|
||||
.option("-v, --vector", "Recreate Vector Tables. This will drop and rebuild all vector tables")
|
||||
.option("-t, --typedef", "Generate typescript type definitions")
|
||||
.option("--dry-run", "Print the schema changes that would be applied, without applying them")
|
||||
.option("-y, --yes", "Apply destructive changes (dropped tables / columns) without confirmation")
|
||||
.action(async (opts) => {
|
||||
console.log(`Starting process ...`);
|
||||
const { config, dbSchema } = await init();
|
||||
const config = global.CONFIG;
|
||||
const dbSchema = global.DB_SCHEMA;
|
||||
const DbClient = global.SQLITE_CLIENT;
|
||||
const { ROOT_DIR, BUN_SQLITE_TEMP_DB_FILE_PATH } = grabDirNames();
|
||||
const { db_file_path } = grabDBDir({ config });
|
||||
cpSync(db_file_path, BUN_SQLITE_TEMP_DB_FILE_PATH);
|
||||
const isVector = Boolean(opts.vector || opts.v);
|
||||
const isTypeDef = Boolean(opts.typedef || opts.t);
|
||||
const finaldbSchema = appendDefaultFieldsToDbSchema({
|
||||
dbSchema,
|
||||
});
|
||||
const params = {
|
||||
db: DbClient,
|
||||
db_schema: finaldbSchema,
|
||||
recreate_vector_table: isVector,
|
||||
};
|
||||
/**
|
||||
* Plan: run the sync in a transaction that is rolled back
|
||||
*/
|
||||
const plan = [];
|
||||
try {
|
||||
const isVector = Boolean(opts.vector || opts.v);
|
||||
const isTypeDef = Boolean(opts.typedef || opts.t);
|
||||
const finaldbSchema = appendDefaultFieldsToDbSchema({
|
||||
dbSchema,
|
||||
createDBSchema({ ...params, dry_run: true, changes: plan });
|
||||
}
|
||||
catch (error) {
|
||||
console.error(chalk.red(`Schema sync ERROR => ${error.message}`));
|
||||
process.exit(1);
|
||||
}
|
||||
const destructive = plan.filter((change) => change.destructive);
|
||||
if (opts.dryRun) {
|
||||
if (!plan.length) {
|
||||
console.log(chalk.green(`Schema is up to date.`));
|
||||
}
|
||||
else {
|
||||
console.log(chalk.bold(`Planned schema changes:\n`));
|
||||
for (const change of plan) {
|
||||
console.log(change.destructive
|
||||
? chalk.red(` ${change.description}`)
|
||||
: ` ${change.description}`);
|
||||
}
|
||||
if (destructive.length) {
|
||||
console.log(chalk.red(`\n${destructive.length} destructive change(s) (in red) would discard data.`));
|
||||
}
|
||||
}
|
||||
process.exit(0);
|
||||
}
|
||||
if (destructive.length && !opts.yes) {
|
||||
console.log(chalk.yellow(`\nThese changes will permanently discard data:\n`));
|
||||
for (const change of destructive) {
|
||||
console.log(chalk.red(` ${change.description}`));
|
||||
}
|
||||
console.log();
|
||||
if (!process.stdin.isTTY) {
|
||||
console.error(chalk.red(`Refusing to apply destructive changes non-interactively. Re-run with --yes to apply them.`));
|
||||
process.exit(1);
|
||||
}
|
||||
const proceed = await confirm({
|
||||
message: `Apply ${destructive.length} destructive change(s)?`,
|
||||
default: false,
|
||||
});
|
||||
const manager = new SQLiteSchemaManager({
|
||||
schema: finaldbSchema,
|
||||
recreate_vector_table: isVector,
|
||||
if (!proceed) {
|
||||
console.log(chalk.dim(`Schema sync cancelled.`));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
snapshotDb({ db: DbClient, dst: BUN_SQLITE_TEMP_DB_FILE_PATH });
|
||||
try {
|
||||
createDBSchema({
|
||||
...params,
|
||||
allow_destructive: opts.yes
|
||||
? true
|
||||
: new Set(destructive.map((c) => c.description)),
|
||||
});
|
||||
await manager.syncSchema();
|
||||
manager.close();
|
||||
DbClient.close();
|
||||
if (isTypeDef && config.typedef_file_path) {
|
||||
const out_file = path.resolve(ROOT_DIR, config.typedef_file_path);
|
||||
dbSchemaToTypeDef({
|
||||
@@ -47,7 +105,11 @@ export default function () {
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
cpSync(BUN_SQLITE_TEMP_DB_FILE_PATH, db_file_path);
|
||||
DbClient.close();
|
||||
replaceDbFile({
|
||||
src: BUN_SQLITE_TEMP_DB_FILE_PATH,
|
||||
db_file_path,
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
Vendored
+3
-3
@@ -1,5 +1,4 @@
|
||||
import { Command } from "commander";
|
||||
import init from "../functions/init";
|
||||
import dbSchemaToTypeDef from "../lib/sqlite/schema-to-typedef";
|
||||
import path from "path";
|
||||
import grabDirNames from "../data/grab-dir-names";
|
||||
@@ -10,7 +9,8 @@ export default function () {
|
||||
.description("Build DB From Schema")
|
||||
.action(async (opts) => {
|
||||
console.log(`Creating Type Definition From DB Schema ...`);
|
||||
const { config, dbSchema } = await init();
|
||||
const config = global.CONFIG;
|
||||
const dbSchema = global.DB_SCHEMA;
|
||||
const { ROOT_DIR } = grabDirNames();
|
||||
const finaldbSchema = appendDefaultFieldsToDbSchema({ dbSchema });
|
||||
if (config.typedef_file_path) {
|
||||
@@ -22,7 +22,7 @@ export default function () {
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.error(``);
|
||||
console.error(`\`typedef_file_path\` is required in your config`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`${chalk.bold(chalk.green(`Typedef gen success!`))}`);
|
||||
|
||||
Reference in New Issue
Block a user