Major version update. Major bugfixes. Security vulnerabilites fixed

This commit is contained in:
2026-10-14 03:02:07 +01:00
parent 4e47bd8ce0
commit 7c095f6f16
112 changed files with 2479 additions and 1219 deletions
+7
View File
@@ -0,0 +1,7 @@
import { Database } from "bun:sqlite";
import type { BunSQLiteConfig } from "../types";
type Params = {
config: BunSQLiteConfig;
};
export default function grabSQLiteClient({ config }: Params): Database;
export {};
+21
View File
@@ -0,0 +1,21 @@
import { Database } from "bun:sqlite";
import * as sqliteVec from "sqlite-vec";
import grabDBDir from "../utils/grab-db-dir";
/** Reuse one connection per database file. */
const clientCache = new Map();
export default function grabSQLiteClient({ config }) {
const { db_file_path } = grabDBDir({ config });
const cached = clientCache.get(db_file_path);
if (cached) {
return cached;
}
const SQLiteClient = new Database(db_file_path, {
create: true,
});
sqliteVec.load(SQLiteClient);
if (config.wal_mode) {
SQLiteClient.run("PRAGMA journal_mode = WAL;");
}
clientCache.set(db_file_path, SQLiteClient);
return SQLiteClient;
}
+18 -2
View File
@@ -1,2 +1,18 @@
import type { BunSQLiteConfigReturn } from "../types";
export default function init(): Promise<BunSQLiteConfigReturn>;
import type { Database } from "bun:sqlite";
import type { BunSQLiteConfig, BunSQLiteConfigReturn, BUN_SQLITE_DatabaseSchemaType } from "../types";
/**
* # Declare Global Variables
*/
declare global {
var CONFIG: BunSQLiteConfig;
var DB_SCHEMA: BUN_SQLITE_DatabaseSchemaType;
var SQLITE_CLIENT: Database;
var CONFIG_FILE_PATH: string;
var SCHEMA_FILE_PATH: string;
}
/**
* # Load config, schema and the SQLite client into globals
* @description Runs once per process. Later calls return the loaded
* globals.
*/
export default function init(): BunSQLiteConfigReturn;
+79 -39
View File
@@ -2,45 +2,85 @@ import path from "path";
import fs from "fs";
import { AppData } from "../data/app-data";
import grabDirNames from "../data/grab-dir-names";
export default async function init() {
try {
const { ROOT_DIR } = grabDirNames();
const { ConfigFileName } = AppData;
const ConfigFilePath = path.join(ROOT_DIR, ConfigFileName);
if (!fs.existsSync(ConfigFilePath)) {
console.log("ConfigFilePath", ConfigFilePath);
console.error(`Please create a \`${ConfigFileName}\` file at the root of your project.`);
process.exit(1);
}
const ConfigImport = await import(ConfigFilePath);
const Config = ConfigImport["default"];
if (!Config.db_name) {
console.error(`\`db_name\` is required in your config`);
process.exit(1);
}
if (!Config.db_schema_file_name) {
console.error(`\`db_schema_file_name\` is required in your config`);
process.exit(1);
}
let db_dir = ROOT_DIR;
if (Config.db_dir) {
db_dir = path.resolve(ROOT_DIR, Config.db_dir);
if (!fs.existsSync(Config.db_dir)) {
fs.mkdirSync(Config.db_dir, { recursive: true });
}
}
const DBSchemaFilePath = path.join(db_dir, Config.db_schema_file_name);
const DbSchemaImport = await import(DBSchemaFilePath);
const DbSchema = DbSchemaImport["default"];
const backup_dir = Config.db_backup_dir || AppData["DefaultBackupDirName"];
const BackupDir = path.resolve(db_dir, backup_dir);
if (!fs.existsSync(BackupDir)) {
fs.mkdirSync(BackupDir, { recursive: true });
}
return { config: Config, dbSchema: DbSchema };
import setSQLiteClient from "./set-sqlite-client";
import grabDBDir from "../utils/grab-db-dir";
import { loadDataFile, resolveAndLoadDataFile, supportedDataFileNames, } from "../utils/resolve-and-load-data-file";
/**
* # Load config, schema and the SQLite client into globals
* @description Runs once per process. Later calls return the loaded
* globals.
*/
export default function init() {
if (global.CONFIG && global.DB_SCHEMA && global.SQLITE_CLIENT) {
return { config: global.CONFIG, dbSchema: global.DB_SCHEMA };
}
catch (error) {
console.error(`Initialization ERROR => ` + error.message);
process.exit(1);
const { ROOT_DIR } = grabDirNames();
const { ConfigFileName } = AppData;
const loadedConfig = resolveAndLoadDataFile(ROOT_DIR, ConfigFileName);
if (!loadedConfig) {
throw new Error(`Please create a ${supportedDataFileNames(ConfigFileName)} file at the root of your project. (Looked in ${ROOT_DIR})`);
}
const Config = loadedConfig.data;
if (!Config || typeof Config !== "object") {
throw new Error(`Invalid config in \`${loadedConfig.path}\`. Expected a config object${isCodeFile(loadedConfig) ? " (export default)" : ""}.`);
}
if (!Config.db_name) {
throw new Error(`\`db_name\` is required in your config`);
}
const { db_dir, backup_dir } = grabDBDir({ config: Config });
if (!fs.existsSync(db_dir)) {
fs.mkdirSync(db_dir, { recursive: true });
}
const loadedSchema = loadSchema({ config: Config, db_dir });
const DbSchema = loadedSchema.data;
if (!DbSchema || typeof DbSchema !== "object") {
throw new Error(`Invalid schema in \`${loadedSchema.path}\`. Expected a schema object${isCodeFile(loadedSchema) ? " (export default)" : ""}.`);
}
if (!fs.existsSync(backup_dir)) {
fs.mkdirSync(backup_dir, { recursive: true });
}
global.CONFIG = Config;
global.DB_SCHEMA = DbSchema;
global.CONFIG_FILE_PATH = loadedConfig.path;
global.SCHEMA_FILE_PATH = loadedSchema.path;
setSQLiteClient({ config: Config });
return { config: Config, dbSchema: DbSchema };
}
/**
* # Load the schema file
* @description Uses `db_schema_file_name` when set, otherwise
* `schema.ts|js|json|yaml|yml` in `db_dir`.
*/
function loadSchema({ config, db_dir, }) {
if (config.db_schema_file_name) {
const schema_file_path = path.join(db_dir, config.db_schema_file_name);
const extension = path.extname(schema_file_path);
const supported = AppData.SupportedDataFileExtensions.find((ext) => ext === extension);
if (!supported) {
throw new Error(`Unsupported schema file \`${config.db_schema_file_name}\`. Use one of: ${AppData.SupportedDataFileExtensions.join(", ")}`);
}
if (!fs.existsSync(schema_file_path)) {
throw new Error(`Schema file not found: ${schema_file_path}`);
}
const resolved = {
path: schema_file_path,
basename: path.basename(schema_file_path),
extension: supported,
format: supported === ".yml"
? "yaml"
: supported.slice(1),
};
return {
...resolved,
data: loadDataFile(resolved),
};
}
const loaded = resolveAndLoadDataFile(db_dir, AppData.DbSchemaFileName);
if (!loaded) {
throw new Error(`Please create a schema file (${supportedDataFileNames(AppData.DbSchemaFileName)}) in \`${db_dir}\`, or set \`db_schema_file_name\` in your config.`);
}
return loaded;
}
function isCodeFile(file) {
return file.format === "ts" || file.format === "js";
}
+6
View File
@@ -0,0 +1,6 @@
import type { BunSQLiteConfig } from "../types";
type Params = {
config: BunSQLiteConfig;
};
export default function setSQLiteClient({ config }: Params): void;
export {};
+4
View File
@@ -0,0 +1,4 @@
import grabSQLiteClient from "./grab-sqlite-client";
export default function setSQLiteClient({ config }) {
global.SQLITE_CLIENT = grabSQLiteClient({ config });
}