🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

twilight.db

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

twilight.db - npm Package Compare versions

Comparing version
0.0.6
to
0.0.7
+343
source/Database/twilight.js
const fs = require('fs');
const path = require('path');
const mysql = require('mysql');
const yaml = require('js-yaml');
const BSON = require('bson');
class TwilightDB {
constructor(filename, format = 'json') {
this.filename = filename;
this.data = {};
this.format = format;
this.initialize();
}
initialize() {
try {
if (this.format === 'json' || this.format === 'bson') {
const filePath = this.filename;
if (fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(filePath, 'utf8');
if (this.format === 'json') {
this.data = JSON.parse(fileContent);
} else if (this.format === 'bson') {
const bson = new BSON();
this.data = bson.deserialize(Buffer.from(fileContent, 'base64'));
}
} else {
this.save();
}
} else if (this.format === 'mysql') {
this.connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'flexidb',
});
this.connection.connect();
const query = 'CREATE TABLE IF NOT EXISTS data (key VARCHAR(255), value VARCHAR(255))';
this.connection.query(query, (error) => {
if (error) {
console.error('Error creating table:', error);
}
});
const selectQuery = 'SELECT * FROM data';
this.connection.query(selectQuery, (error, results) => {
if (error) {
console.error('Error loading data from MySQL:', error);
} else {
for (const row of results) {
this.data[row.key] = row.value;
}
}
});
} else if (this.format === 'yaml') {
const filePath = this.filename;
if (fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(filePath, 'utf8');
this.data = yaml.load(fileContent);
} else {
this.save();
}
}
} catch (error) {
console.error('Error initializing database:', error);
}
}
save() {
try {
if (this.format === 'json' || this.format === 'bson') {
const filePath = this.filename;
if (this.format === 'json') {
fs.writeFileSync(filePath, JSON.stringify(this.data));
} else if (this.format === 'bson') {
const bson = new BSON();
const bsonData = bson.serialize(this.data);
const base64Data = bsonData.toString('base64');
fs.writeFileSync(filePath, base64Data);
}
} else if (this.format === 'mysql') {
const deleteQuery = 'DELETE FROM data';
this.connection.query(deleteQuery, (error) => {
if (error) {
console.error('Error deleting data from MySQL:', error);
} else {
const insertQuery = 'INSERT INTO data (key, value) VALUES ?';
const values = Object.entries(this.data).map(([key, value]) => [key, value]);
this.connection.query(insertQuery, [values], (error) => {
if (error) {
console.error('Error saving data to MySQL:', error);
}
});
}
});
} else if (this.format === 'yaml') {
const filePath = this.filename;
const yamlData = yaml.dump(this.data);
fs.writeFileSync(filePath, yamlData);
}
} catch (error) {
console.error('Error saving database:', error);
}
}
create(key, value) {
if (this.data[key]) {
console.error('Error creating record: Key already exists');
return;
}
this.data[key] = value;
this.save();
}
read(key) {
return this.data[key];
}
update(key, value) {
if (!this.data[key]) {
console.error('Error updating record: Key does not exist');
return;
}
this.data[key] = value;
this.save();
}
delete(key) {
delete this.data[key];
this.save();
}
query(filterFunc) {
return Object.entries(this.data).filter(([key, value]) => filterFunc(key, value));
}
connectMySQL(config) {
this.connection = mysql.createConnection(config);
this.connection.connect();
}
closeConnection() {
this.connection.end();
}
createIndex(key) {
if (!Array.isArray(this.data.__indices)) {
this.data.__indices = [];
}
this.data.__indices.push(key);
this.save();
}
getIndexValues() {
if (!Array.isArray(this.data.__indices)) {
return [];
}
return this.data.__indices.map((key) => this.data[key]);
}
startTransaction() {
this.transaction = {};
}
commitTransaction() {
Object.assign(this.data, this.transaction);
this.transaction = null;
this.save();
}
rollbackTransaction() {
this.transaction = null;
}
validateData(key, value) {
if (key === 'myArray') {
if (!Array.isArray(value)) {
console.error(`Error setting data: Invalid data for key '${key}'. Value must be an array.`);
return false;
}
for (const element of value) {
if (typeof element !== 'string') {
console.error(`Error setting data: Invalid data for key '${key}'. Array elements must be strings.`);
return false;
}
}
}
// Add other data validation rules here
return true;
}
set(key, value) {
if (this.validateData(key, value)) {
if (this.transaction) {
this.transaction[key] = value;
} else {
this.data[key] = value;
this.save();
}
} else {
console.error('Error setting data: Invalid data');
}
}
backup(backupFilename) {
const backupData = {
data: this.data,
format: this.format,
};
fs.writeFileSync(backupFilename, JSON.stringify(backupData));
}
restore(backupFilename) {
try {
const backupData = JSON.parse(fs.readFileSync(backupFilename, 'utf8'));
this.data = backupData.data;
this.format = backupData.format;
console.log('Database restored from backup:', backupFilename);
} catch (error) {
console.error('Error restoring database from backup:', error);
}
}
createDatabase(databaseName) {
const query = `CREATE DATABASE IF NOT EXISTS ${databaseName}`;
this.connection.query(query, (error) => {
if (error) {
console.error('Error creating database:', error);
} else {
console.log('Database created successfully:', databaseName);
}
});
}
deleteDatabase(databaseName) {
const query = `DROP DATABASE IF EXISTS ${databaseName}`;
this.connection.query(query, (error) => {
if (error) {
console.error('Error deleting database:', error);
} else {
console.log('Database deleted successfully:', databaseName);
}
});
}
renameDatabase(databaseName, newDatabaseName) {
const query = `RENAME DATABASE ${databaseName} TO ${newDatabaseName}`;
this.connection.query(query, (error) => {
if (error) {
console.error('Error renaming database:', error);
} else {
console.log('Database renamed successfully:', databaseName, 'to', newDatabaseName);
}
});
}
createTable(tableName, columns) {
const columnDefinitions = columns.map(column => `${column.name} ${column.type}`).join(', ');
const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columnDefinitions})`;
this.connection.query(query, (error) => {
if (error) {
console.error('Error creating table:', error);
} else {
console.log('Table created successfully:', tableName);
}
});
}
addColumn(tableName, columnName, columnType) {
const query = `ALTER TABLE ${tableName} ADD COLUMN ${columnName} ${columnType}`;
this.connection.query(query, (error) => {
if (error) {
console.error('Error adding column:', error);
} else {
console.log('Column added successfully:', columnName, 'to', tableName);
}
});
}
removeColumn(tableName, columnName) {
const query = `ALTER TABLE ${tableName} DROP COLUMN ${columnName}`;
this.connection.query(query, (error) => {
if (error) {
console.error('Error removing column:', error);
} else {
console.log('Column removed successfully:', columnName, 'from', tableName);
}
});
}
createIndex(tableName, columnName) {
const indexName = `${tableName}_${columnName}_index`;
const query = `CREATE INDEX ${indexName} ON ${tableName} (${columnName})`;
this.connection.query(query, (error) => {
if (error) {
console.error('Error creating index:', error);
} else {
console.log('Index created successfully:', indexName);
}
});
}
defineRelationship(tableName1, columnName1, tableName2, columnName2) {
const foreignKeyName = `${tableName1}_${columnName1}_fk`;
const query = `ALTER TABLE ${tableName1} ADD CONSTRAINT ${foreignKeyName} FOREIGN KEY (${columnName1}) REFERENCES ${tableName2}(${columnName2})`;
this.connection.query(query, (error) => {
if (error) {
console.error('Error defining relationship:', error);
} else {
console.log('Relationship defined successfully between', tableName1, 'and', tableName2);
}
});
}
push(key, ...values) {
if (!Array.isArray(this.data[key])) {
this.data[key] = [];
}
this.data[key].push(...values);
this.save();
}
all() {
return Object.entries(this.data).map(([key, value]) => ({ key, value }));
}
has(key) {
return key in this.data;
}
get(key) {
return this.data[key];
}
}
module.exports = TwilightDB;
+25
-25
{
"name": "twilight.db",
"version": "0.0.6",
"description": "Créated By Weatrix",
"main": "index.js",
"scripts": {
"test": "node index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Weatrixcik/TwilightDB.git"
},
"keywords": [],
"author": "Weatrix",
"license": "MIT",
"bugs": {
"url": "https://github.com/Weatrixcik/TwilightDB/issues"
},
"homepage": "https://github.com/Weatrixcik/TwilightDB#readme",
"dependencies": {
"bson": "^5.3.0",
"fs": "^0.0.1-security",
"js-yaml": "^4.1.0",
"mysql": "^2.18.1"
}
}
"name": "twilight.db",
"version": "0.0.7",
"description": "Créated By Weatrix",
"main": "index.js",
"scripts": {
"test": "node index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Weatrixcik/TwilightDB.git"
},
"keywords": [],
"author": "Weatrix",
"license": "MIT",
"bugs": {
"url": "https://github.com/Weatrixcik/TwilightDB/issues"
},
"homepage": "https://github.com/Weatrixcik/TwilightDB#readme",
"dependencies": {
"bson": "^5.3.0",
"fs": "^0.0.1-security",
"js-yaml": "^4.1.0",
"mysql": "^2.18.1"
}
}

@@ -123,2 +123,2 @@ # Twilight.db: Veritabanınızı Kolayca Yönetin

- TwilightDB ile veritabanı işlemlerini kolaylaştırın ve projenizde verilerinizi güvenle yönetin.
- TwilightDB ile veritabanı işlemlerini kolaylaştırın ve projenizde verilerinizi güvenle yönetin.

@@ -1,6 +0,5 @@

const green = (message) => `\x1b[32m${message}\x1b[0m`;
const red = (message) => `\x1b[31m${message}\x1b[0m`;
const yellow = (message) => `\x1b[33m${message}\x1b[0m`;
const advertisement = `${yellow("( twilight.db ) => Bilgilendirme:")} ${green("Destek İçin; https://discord.gg/luppux")}`;
const advertisement = `${yellow("( twilight.db ) => Bilgilendirme:")} ${green("Discord (Weatrix)")}`;

@@ -7,0 +6,0 @@ class DatabaseError extends Error {

declare module 'twilight.db' {
export class BsonDatabase {
public constructor();
private addSubtract;
private setArray;
public all(): { id: string; value: any }[];
public get(key: string): null;
public fetch(key: string): null;
public set(key: string, value: any): boolean;
public has(key: string): boolean;
public delete(key: string): boolean;
public deleteAll(): boolean;
public add(key: string, value: number): number;
public sub(key: string, value: number): number;
public push(key: string, value: any | any[]): any[];
public pull(
key: string,
value: any | any[] | ((data: any) => boolean)
): any[];
}
export class JsonDatabase<V> {
private cache: { [key: string]: V };
public path: string;
public maxDataSize: number;
public size: number;
public constructor(options?: IOptions);
public set(key: string, value: V, autoWrite?: boolean): V;
public get(key: string, defaultValue?: V): V;
public fetch(key: string, defaultValue?: V): V;
public exists(key: string): boolean;
public has(key: string): boolean;
public all(limit?: number): Array<Schema<V>>;
public fetchAll(limit?: number): Array<Schema<V>>;
public toJSON(limit?: number): { [key: string]: V };
public delete(key: string, autoWrite?: boolean): void;
public deleteAll(): void;
public type(key: string): keyof V | 'undefined' | 'function';
public pull(
key: string,
callbackfn: (element: any, index: number, array: any[]) => boolean,
multiple?: boolean,
thisArg?: any
): V;
public valueArray(): V[];
public keyArray(): string[];
public math(
key: string,
operator: '+' | '-' | '*' | '/' | '%',
value: number,
goToNegative?: boolean
): V;
public add(key: string, value: V): V;
public substr(key: string, value: V, goToNegative?: boolean): V;
public push(key: string, value: any): V;
public includes(key: string): Array<Schema<V>>;
public startsWith(key: string): Array<Schema<V>>;
public filter(
callbackfn: (value: Schema<V>, index: number, array: Schema<V>[]) => boolean,
thisArg?: any
): Array<Schema<V>>;
public sort(
callbackfn: (a: Schema<V>, b: Schema<V>) => number,
thisArg?: any
): Array<Schema<V>>;
public destroy(): void;
public findAndDelete(
callbackfn: (key: string, value: V) => boolean,
thisArg?: any
): number;
public get info(): IInfo;
}
export class YamlDatabase<V> {
private cache: { [key: string]: V };
public path: string;
public maxDataSize: number;
public size: number;
public constructor(options?: IOptions);
public set(key: string, value: V, autoWrite?: boolean): V;
public get(key: string, defaultValue?: V): V;
public fetch(key: string, defaultValue?: V): V;
public exists(key: string): boolean;
public has(key: string): boolean;
public all(limit?: number): Array<Schema<V>>;
public fetchAll(limit?: number): Array<Schema<V>>;
public toJSON(limit?: number): { [key: string]: V };
public delete(key: string, autoWrite?: boolean): void;
public deleteAll(): void;
public type(key: string): keyof V | 'undefined' | 'function';
public pull(
key: string,
callbackfn: (element: any, index: number, array: any[]) => boolean,
multiple?: boolean,
thisArg?: any
): V;
public valueArray(): V[];
public keyArray(): string[];
public math(
key: string,
operator: '+' | '-' | '*' | '/' | '%',
value: number,
goToNegative?: boolean
): V;
public add(key: string, value: V): V;
public substr(key: string, value: V, goToNegative?: boolean): V;
public push(key: string, value: any): V;
public includes(key: string): Array<Schema<V>>;
public startsWith(key: string): Array<Schema<V>>;
public filter(
callbackfn: (value: Schema<V>, index: number, array: Schema<V>[]) => boolean,
thisArg?: any
): Array<Schema<V>>;
public sort(
callbackfn: (a: Schema<V>, b: Schema<V>) => number,
thisArg?: any
): Array<Schema<V>>;
public destroy(): void;
public findAndDelete(
callbackfn: (key: string, value: V) => boolean,
thisArg?: any
): number;
public get info(): IInfo;
}
export class DatabaseError extends Error {
public constructor(message: string);
public get name(): string;
}
export interface Schema<T> {
ID: string;
data: T;
}
export interface IOptions {
maxDataSize?: number;
databasePath?: string;
}
export interface IInfo {
version: string;
size: number;
}
}
export class BsonDatabase {
public constructor();
private addSubtract;
private setArray;
public all(): { id: string; value: any }[];
public get(key: string): null;
public fetch(key: string): null;
public set(key: string, value: any): boolean;
public has(key: string): boolean;
public delete(key: string): boolean;
public deleteAll(): boolean;
public add(key: string, value: number): number;
public sub(key: string, value: number): number;
public push(key: string, value: any | any[]): any[];
public pull(
key: string,
value: any | any[] | ((data: any) => boolean)
): any[];
}
export class JsonDatabase<V> {
private cache: { [key: string]: V };
public path: string;
public maxDataSize: number;
public size: number;
public constructor(options?: IOptions);
public set(key: string, value: V, autoWrite?: boolean): V;
public get(key: string, defaultValue?: V): V;
public fetch(key: string, defaultValue?: V): V;
public exists(key: string): boolean;
public has(key: string): boolean;
public all(limit?: number): Array<Schema<V>>;
public fetchAll(limit?: number): Array<Schema<V>>;
public toJSON(limit?: number): { [key: string]: V };
public delete(key: string, autoWrite?: boolean): void;
public deleteAll(): void;
public type(key: string): keyof V | 'undefined' | 'function';
public pull(
key: string,
callbackfn: (element: any, index: number, array: any[]) => boolean,
multiple?: boolean,
thisArg?: any
): V;
public valueArray(): V[];
public keyArray(): string[];
public math(
key: string,
operator: '+' | '-' | '*' | '/' | '%',
value: number,
goToNegative?: boolean
): V;
public add(key: string, value: V): V;
public substr(key: string, value: V, goToNegative?: boolean): V;
public push(key: string, value: any): V;
public includes(key: string): Array<Schema<V>>;
public startsWith(key: string): Array<Schema<V>>;
public filter(
callbackfn: (value: Schema<V>, index: number, array: Schema<V>[]) => boolean,
thisArg?: any
): Array<Schema<V>>;
public sort(
callbackfn: (a: Schema<V>, b: Schema<V>) => number,
thisArg?: any
): Array<Schema<V>>;
public destroy(): void;
public findAndDelete(
callbackfn: (key: string, value: V) => boolean,
thisArg?: any
): number;
public get info(): IInfo;
}
export class YamlDatabase<V> {
private cache: { [key: string]: V };
public path: string;
public maxDataSize: number;
public size: number;
public constructor(options?: IOptions);
public set(key: string, value: V, autoWrite?: boolean): V;
public get(key: string, defaultValue?: V): V;
public fetch(key: string, defaultValue?: V): V;
public exists(key: string): boolean;
public has(key: string): boolean;
public all(limit?: number): Array<Schema<V>>;
public fetchAll(limit?: number): Array<Schema<V>>;
public toJSON(limit?: number): { [key: string]: V };
public delete(key: string, autoWrite?: boolean): void;
public deleteAll(): void;
public type(key: string): keyof V | 'undefined' | 'function';
public pull(
key: string,
callbackfn: (element: any, index: number, array: any[]) => boolean,
multiple?: boolean,
thisArg?: any
): V;
public valueArray(): V[];
public keyArray(): string[];
public math(
key: string,
operator: '+' | '-' | '*' | '/' | '%',
value: number,
goToNegative?: boolean
): V;
public add(key: string, value: V): V;
public substr(key: string, value: V, goToNegative?: boolean): V;
public push(key: string, value: any): V;
public includes(key: string): Array<Schema<V>>;
public startsWith(key: string): Array<Schema<V>>;
public filter(
callbackfn: (value: Schema<V>, index: number, array: Schema<V>[]) => boolean,
thisArg?: any
): Array<Schema<V>>;
public sort(
callbackfn: (a: Schema<V>, b: Schema<V>) => number,
thisArg?: any
): Array<Schema<V>>;
public destroy(): void;
public findAndDelete(
callbackfn: (key: string, value: V) => boolean,
thisArg?: any
): number;
public get info(): IInfo;
}
export class DatabaseError extends Error {
public constructor(message: string);
public get name(): string;
}
export interface Schema<T> {
ID: string;
data: T;
}
export interface IOptions {
maxDataSize?: number;
databasePath?: string;
}
export interface IInfo {
version: string;
size: number;
}
}
const fs = require('fs');
const path = require('path');
const mysql = require('mysql');
const yaml = require('js-yaml');
const BSON = require('bson');
class TwilightDB {
constructor(filename, format = 'json') {
this.filename = filename;
this.data = {};
this.format = format;
this.initialize();
}
initialize() {
try {
if (this.format === 'json' || this.format === 'bson') {
const filePath = this.filename;
if (fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(filePath, 'utf8');
if (this.format === 'json') {
this.data = JSON.parse(fileContent);
} else if (this.format === 'bson') {
const bson = new BSON();
this.data = bson.deserialize(Buffer.from(fileContent, 'base64'));
}
} else {
this.save();
}
} else if (this.format === 'mysql') {
this.connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'flexidb',
});
this.connection.connect();
const query = 'CREATE TABLE IF NOT EXISTS data (key VARCHAR(255), value VARCHAR(255))';
this.connection.query(query, (error) => {
if (error) {
console.error('Error creating table:', error);
}
});
const selectQuery = 'SELECT * FROM data';
this.connection.query(selectQuery, (error, results) => {
if (error) {
console.error('Error loading data from MySQL:', error);
} else {
for (const row of results) {
this.data[row.key] = row.value;
}
}
});
} else if (this.format === 'yaml') {
const filePath = this.filename;
if (fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(filePath, 'utf8');
this.data = yaml.load(fileContent);
} else {
this.save();
}
}
} catch (error) {
console.error('Error initializing database:', error);
}
}
save() {
try {
if (this.format === 'json' || this.format === 'bson') {
const filePath = this.filename;
if (this.format === 'json') {
fs.writeFileSync(filePath, JSON.stringify(this.data));
} else if (this.format === 'bson') {
const bson = new BSON();
const bsonData = bson.serialize(this.data);
const base64Data = bsonData.toString('base64');
fs.writeFileSync(filePath, base64Data);
}
} else if (this.format === 'mysql') {
const deleteQuery = 'DELETE FROM data';
this.connection.query(deleteQuery, (error) => {
if (error) {
console.error('Error deleting data from MySQL:', error);
} else {
const insertQuery = 'INSERT INTO data (key, value) VALUES ?';
const values = Object.entries(this.data).map(([key, value]) => [key, value]);
this.connection.query(insertQuery, [values], (error) => {
if (error) {
console.error('Error saving data to MySQL:', error);
}
});
}
});
} else if (this.format === 'yaml') {
const filePath = this.filename;
const yamlData = yaml.dump(this.data);
fs.writeFileSync(filePath, yamlData);
}
} catch (error) {
console.error('Error saving database:', error);
}
}
create(key, value) {
if (this.data[key]) {
console.error('Error creating record: Key already exists');
return;
}
this.data[key] = value;
this.save();
}
read(key) {
return this.data[key];
}
update(key, value) {
if (!this.data[key]) {
console.error('Error updating record: Key does not exist');
return;
}
this.data[key] = value;
this.save();
}
delete(key) {
delete this.data[key];
this.save();
}
query(filterFunc) {
return Object.entries(this.data).filter(([key, value]) => filterFunc(key, value));
}
connectMySQL(config) {
this.connection = mysql.createConnection(config);
this.connection.connect();
}
closeConnection() {
this.connection.end();
}
createIndex(key) {
if (!Array.isArray(this.data.__indices)) {
this.data.__indices = [];
}
this.data.__indices.push(key);
this.save();
}
getIndexValues() {
if (!Array.isArray(this.data.__indices)) {
return [];
}
return this.data.__indices.map((key) => this.data[key]);
}
startTransaction() {
this.transaction = {};
}
commitTransaction() {
Object.assign(this.data, this.transaction);
this.transaction = null;
this.save();
}
rollbackTransaction() {
this.transaction = null;
}
validateData(key, value) {
if (key === 'myArray') {
if (!Array.isArray(value)) {
console.error(`Error setting data: Invalid data for key '${key}'. Value must be an array.`);
return false;
}
for (const element of value) {
if (typeof element !== 'string') {
console.error(`Error setting data: Invalid data for key '${key}'. Array elements must be strings.`);
return false;
}
}
}
// Add other data validation rules here
return true;
}
set(key, value) {
if (this.validateData(key, value)) {
if (this.transaction) {
this.transaction[key] = value;
} else {
this.data[key] = value;
this.save();
}
} else {
console.error('Error setting data: Invalid data');
}
}
backup(backupFilename) {
const backupData = {
data: this.data,
format: this.format,
};
fs.writeFileSync(backupFilename, JSON.stringify(backupData));
}
restore(backupFilename) {
try {
const backupData = JSON.parse(fs.readFileSync(backupFilename, 'utf8'));
this.data = backupData.data;
this.format = backupData.format;
console.log('Database restored from backup:', backupFilename);
} catch (error) {
console.error('Error restoring database from backup:', error);
}
}
createDatabase(databaseName) {
// Add database creation operations here
}
deleteDatabase(databaseName) {
// Add database deletion operations here
}
renameDatabase(databaseName, newDatabaseName) {
// Add database renaming operations here
}
createTable(tableName, columns) {
// Add table creation operations here
}
addColumn(tableName, columnName, columnType) {
// Add column addition operations here
}
removeColumn(tableName, columnName) {
// Add column removal operations here
}
createIndex(tableName, columnName) {
// Add index creation operations here
}
defineRelationship(tableName1, columnName1, tableName2, columnName2) {
// Add relationship definition operations here
}
push(key, ...values) {
if (!Array.isArray(this.data[key])) {
this.data[key] = [];
}
this.data[key].push(...values);
this.save();
}
all() {
return Object.entries(this.data).map(([key, value]) => ({ key, value }));
}
has(key) {
return key in this.data;
}
get(key) {
return this.data[key];
}
}
module.exports = TwilightDB;