@hedystia/db 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +13 -0
  2. package/dist/_virtual/_rolldown/runtime.mjs +17 -0
  3. package/dist/cache/manager.cjs +137 -0
  4. package/dist/cache/manager.cjs.map +1 -0
  5. package/dist/cache/manager.d.cts +72 -0
  6. package/dist/cache/manager.d.mts +72 -0
  7. package/dist/cache/manager.mjs +140 -0
  8. package/dist/cache/manager.mjs.map +1 -0
  9. package/dist/cache/memory-store.cjs +122 -0
  10. package/dist/cache/memory-store.cjs.map +1 -0
  11. package/dist/cache/memory-store.mjs +122 -0
  12. package/dist/cache/memory-store.mjs.map +1 -0
  13. package/dist/cli/commands/migration.cjs +22 -0
  14. package/dist/cli/commands/migration.cjs.map +1 -0
  15. package/dist/cli/commands/migration.mjs +32 -0
  16. package/dist/cli/commands/migration.mjs.map +1 -0
  17. package/dist/cli/commands/schema.cjs +21 -0
  18. package/dist/cli/commands/schema.cjs.map +1 -0
  19. package/dist/cli/commands/schema.mjs +30 -0
  20. package/dist/cli/commands/schema.mjs.map +1 -0
  21. package/dist/cli.cjs +50 -0
  22. package/dist/cli.cjs.map +1 -0
  23. package/dist/cli.d.cts +1 -0
  24. package/dist/cli.d.mts +1 -0
  25. package/dist/cli.mjs +57 -0
  26. package/dist/cli.mjs.map +1 -0
  27. package/dist/constants.cjs +16 -0
  28. package/dist/constants.cjs.map +1 -0
  29. package/dist/constants.mjs +16 -0
  30. package/dist/constants.mjs.map +1 -0
  31. package/dist/core/database.cjs +158 -0
  32. package/dist/core/database.cjs.map +1 -0
  33. package/dist/core/database.d.cts +74 -0
  34. package/dist/core/database.d.mts +74 -0
  35. package/dist/core/database.mjs +159 -0
  36. package/dist/core/database.mjs.map +1 -0
  37. package/dist/core/repository.cjs +416 -0
  38. package/dist/core/repository.cjs.map +1 -0
  39. package/dist/core/repository.d.cts +110 -0
  40. package/dist/core/repository.d.mts +110 -0
  41. package/dist/core/repository.mjs +416 -0
  42. package/dist/core/repository.mjs.map +1 -0
  43. package/dist/drivers/driver.cjs +11 -0
  44. package/dist/drivers/driver.cjs.map +1 -0
  45. package/dist/drivers/driver.mjs +11 -0
  46. package/dist/drivers/driver.mjs.map +1 -0
  47. package/dist/drivers/file.cjs +336 -0
  48. package/dist/drivers/file.cjs.map +1 -0
  49. package/dist/drivers/file.mjs +337 -0
  50. package/dist/drivers/file.mjs.map +1 -0
  51. package/dist/drivers/index.cjs +28 -0
  52. package/dist/drivers/index.cjs.map +1 -0
  53. package/dist/drivers/index.d.cts +14 -0
  54. package/dist/drivers/index.d.mts +14 -0
  55. package/dist/drivers/index.mjs +28 -0
  56. package/dist/drivers/index.mjs.map +1 -0
  57. package/dist/drivers/mysql.cjs +272 -0
  58. package/dist/drivers/mysql.cjs.map +1 -0
  59. package/dist/drivers/mysql.mjs +272 -0
  60. package/dist/drivers/mysql.mjs.map +1 -0
  61. package/dist/drivers/sql-compiler.cjs +284 -0
  62. package/dist/drivers/sql-compiler.cjs.map +1 -0
  63. package/dist/drivers/sql-compiler.d.cts +66 -0
  64. package/dist/drivers/sql-compiler.d.mts +66 -0
  65. package/dist/drivers/sql-compiler.mjs +276 -0
  66. package/dist/drivers/sql-compiler.mjs.map +1 -0
  67. package/dist/drivers/sqlite.cjs +262 -0
  68. package/dist/drivers/sqlite.cjs.map +1 -0
  69. package/dist/drivers/sqlite.mjs +262 -0
  70. package/dist/drivers/sqlite.mjs.map +1 -0
  71. package/dist/errors.cjs +74 -0
  72. package/dist/errors.cjs.map +1 -0
  73. package/dist/errors.d.cts +46 -0
  74. package/dist/errors.d.mts +46 -0
  75. package/dist/errors.mjs +68 -0
  76. package/dist/errors.mjs.map +1 -0
  77. package/dist/index.cjs +69 -0
  78. package/dist/index.cjs.map +1 -0
  79. package/dist/index.d.cts +15 -0
  80. package/dist/index.d.mts +15 -0
  81. package/dist/index.mjs +21 -0
  82. package/dist/index.mjs.map +1 -0
  83. package/dist/migrations/definition.cjs +20 -0
  84. package/dist/migrations/definition.cjs.map +1 -0
  85. package/dist/migrations/definition.d.cts +18 -0
  86. package/dist/migrations/definition.d.mts +18 -0
  87. package/dist/migrations/definition.mjs +23 -0
  88. package/dist/migrations/definition.mjs.map +1 -0
  89. package/dist/migrations/index.mjs +12 -0
  90. package/dist/migrations/index.mjs.map +1 -0
  91. package/dist/migrations/templates.cjs +39 -0
  92. package/dist/migrations/templates.cjs.map +1 -0
  93. package/dist/migrations/templates.d.cts +16 -0
  94. package/dist/migrations/templates.d.mts +16 -0
  95. package/dist/migrations/templates.mjs +41 -0
  96. package/dist/migrations/templates.mjs.map +1 -0
  97. package/dist/schema/column.cjs +161 -0
  98. package/dist/schema/column.cjs.map +1 -0
  99. package/dist/schema/column.d.cts +120 -0
  100. package/dist/schema/column.d.mts +120 -0
  101. package/dist/schema/column.mjs +161 -0
  102. package/dist/schema/column.mjs.map +1 -0
  103. package/dist/schema/columns/index.cjs +202 -0
  104. package/dist/schema/columns/index.cjs.map +1 -0
  105. package/dist/schema/columns/index.d.cts +141 -0
  106. package/dist/schema/columns/index.d.mts +141 -0
  107. package/dist/schema/columns/index.mjs +182 -0
  108. package/dist/schema/columns/index.mjs.map +1 -0
  109. package/dist/schema/registry.cjs +125 -0
  110. package/dist/schema/registry.cjs.map +1 -0
  111. package/dist/schema/registry.d.cts +66 -0
  112. package/dist/schema/registry.d.mts +66 -0
  113. package/dist/schema/registry.mjs +125 -0
  114. package/dist/schema/registry.mjs.map +1 -0
  115. package/dist/schema/table.cjs +39 -0
  116. package/dist/schema/table.cjs.map +1 -0
  117. package/dist/schema/table.d.cts +17 -0
  118. package/dist/schema/table.d.mts +17 -0
  119. package/dist/schema/table.mjs +39 -0
  120. package/dist/schema/table.mjs.map +1 -0
  121. package/dist/sync/synchronizer.cjs +43 -0
  122. package/dist/sync/synchronizer.cjs.map +1 -0
  123. package/dist/sync/synchronizer.d.cts +22 -0
  124. package/dist/sync/synchronizer.d.mts +22 -0
  125. package/dist/sync/synchronizer.mjs +43 -0
  126. package/dist/sync/synchronizer.mjs.map +1 -0
  127. package/dist/types.d.cts +229 -0
  128. package/dist/types.d.mts +229 -0
  129. package/dist/utils/fs.cjs +24 -0
  130. package/dist/utils/fs.cjs.map +1 -0
  131. package/dist/utils/fs.mjs +26 -0
  132. package/dist/utils/fs.mjs.map +1 -0
  133. package/dist/utils/index.mjs +14 -0
  134. package/dist/utils/index.mjs.map +1 -0
  135. package/dist/utils/naming.cjs +13 -0
  136. package/dist/utils/naming.cjs.map +1 -0
  137. package/dist/utils/naming.mjs +16 -0
  138. package/dist/utils/naming.mjs.map +1 -0
  139. package/dist/utils/stable-stringify.cjs +19 -0
  140. package/dist/utils/stable-stringify.cjs.map +1 -0
  141. package/dist/utils/stable-stringify.mjs +22 -0
  142. package/dist/utils/stable-stringify.mjs.map +1 -0
  143. package/package.json +64 -27
  144. package/readme.md +87 -105
  145. package/index.d.ts +0 -65
  146. package/index.js +0 -1
package/readme.md CHANGED
@@ -1,137 +1,119 @@
1
- ## Installation
2
-
3
- ```
4
- npm i @hedystia/db
5
-
6
- yarn add @hedystia/db
7
- ```
8
-
9
- ## Nodejs Version
10
-
11
- - `v18.0.0` or higher
12
-
13
- ## Links
14
-
15
- - [Discord](https://discord.gg/aXvuUpvRQs) [Hedystia Discord]
16
- - [Discord_Bot](https://hedystia.com) [Hedystia Bot]
17
- - [Docs](https://docs.hedystia.com/db/start) [Hedystia Docs]
18
-
19
- ## Example
20
-
21
- ```js
22
- const { default: Database } = require("@hedystia/db");
23
-
24
- // Create a file named database.ht and enter the password
25
- const database = new Database("./database.ht", "password");
26
-
27
- // You can only use it once to create the table after that you can no longer use it.
28
- database.createTable("users", ["id", "name", "email"]);
29
-
30
- database.insert("users", { id: "1", name: "John Doe", email: "jdoe@example.com" });
1
+ # @hedystia/db
31
2
 
32
- database.insert("users", { id: "2", name: "María", email: "maria@example.com" });
3
+ Next-gen TypeScript ORM for building type-safe database layers at lightspeed.
33
4
 
34
- const users = database.select("users");
35
-
36
- console.log("----------------------------------");
37
-
38
- console.log(users);
39
-
40
- database.addColumn("users", "phone");
41
-
42
- database.addColumn("users", "lang", "en-US");
43
-
44
- const newUsersPhone = database.select("users");
5
+ ## Installation
45
6
 
46
- console.log("----------------------------------");
7
+ ```bash
8
+ bun add @hedystia/db
9
+ ```
47
10
 
48
- console.log(newUsersPhone);
11
+ ### Database Drivers
49
12
 
50
- database.deleteColumn("users", "phone");
13
+ Install the driver for your database. The ORM will automatically detect and use the most appropriate library available.
51
14
 
52
- const oldUsersPhone = database.select("users");
15
+ #### SQLite Driver
16
+ Supports multiple libraries in the following priority:
17
+ 1. `better-sqlite3`
18
+ 2. `sqlite3`
19
+ 3. `sql.js`
20
+ 4. `bun:sqlite`
53
21
 
54
- console.log("----------------------------------");
22
+ ```bash
23
+ # You can install any of these
55
24
 
56
- console.log(oldUsersPhone);
25
+ bun add better-sqlite3
26
+ bun add sqlite3
27
+ bun add sql.js
57
28
 
58
- const userJohn = database.select("users", { name: "John Doe" });
29
+ # Or use bun:sqlite if you are using Bun
30
+ ```
59
31
 
60
- console.log("----------------------------------");
32
+ #### MySQL & MariaDB Driver
33
+ Supports both `mysql2` and `mysql` libraries.
34
+ - **Naming**: Use `database: "mysql"` or `database: "mariadb"`.
35
+ - **MariaDB**: Fully supported through the same drivers.
61
36
 
62
- console.log(userJohn);
37
+ ```bash
38
+ bun add mysql2 # Preferred
39
+ # or
40
+ bun add mysql
41
+ ```
63
42
 
64
- database.delete("users", { name: "María" });
43
+ # File-based (no extra install needed)
65
44
 
66
- const users2 = database.select("users");
45
+ ## Quick Start
67
46
 
68
- console.log("----------------------------------");
47
+ ### Define your schema
69
48
 
70
- console.log(users2);
49
+ ```ts
50
+ import { table, integer, varchar, text } from "@hedystia/db";
71
51
 
72
- database.update("users", { id: "1" }, { name: "Jane Doe", lang: "es-ES" });
52
+ export const users = table("users", {
53
+ id: integer().primaryKey().autoIncrement(),
54
+ name: varchar(255).notNull(),
55
+ email: varchar(255).unique(),
56
+ age: integer().default(0),
57
+ });
73
58
 
74
- const users3 = database.select("users");
59
+ export const posts = table("posts", {
60
+ id: integer().primaryKey().autoIncrement(),
61
+ userId: integer().references(() => users.id, { onDelete: "CASCADE" }),
62
+ title: varchar(255).notNull(),
63
+ content: text(),
64
+ });
65
+ ```
75
66
 
76
- console.log("----------------------------------");
67
+ > **Note:** The `d.xxx()` prefix style (e.g., `d.integer()`) is still supported for backward compatibility.
77
68
 
78
- console.log(users3);
69
+ ### Create the database
79
70
 
80
- database.dropAll();
71
+ ```ts
72
+ import { database } from "@hedystia/db";
73
+ import { users, posts } from "./schemas";
81
74
 
82
- const users4 = database.select("users");
75
+ const db = database({
76
+ schemas: [users, posts],
77
+ database: "sqlite",
78
+ connection: { filename: "./data.db" },
79
+ syncSchemas: true,
80
+ cache: true,
81
+ });
83
82
 
84
- console.log("----------------------------------");
83
+ await db.initialize();
84
+ ```
85
85
 
86
- console.log(users4);
86
+ ### Query your data
87
87
 
88
- database.enableMigrations();
88
+ ```ts
89
+ // Insert
90
+ const user = await db.users.insert({ name: "Alice", email: "alice@example.com" });
89
91
 
90
- database.createMigration(
91
- {
92
- id: "cdaa5095-0c11-4878-8d89-c9be41215e57",
93
- description: "Description",
94
- timestamp: Date.now(),
95
- },
96
- () => {
97
- database.createTableIfNotExists("test_migration", ["name"]);
98
- database.insert("test_migration", { name: "John" });
99
- },
100
- );
92
+ // Find
93
+ const allUsers = await db.users.find();
94
+ const alice = await db.users.findFirst({ where: { name: "Alice" } });
101
95
 
102
- const migrations = database.select("migrations");
96
+ // Update
97
+ await db.users.update({ where: { id: 1 }, data: { age: 26 } });
103
98
 
104
- console.log("----------------------------------");
99
+ // Delete
100
+ await db.users.delete({ where: { id: 1 } });
105
101
 
106
- console.log(migrations);
102
+ // Relations
103
+ const usersWithPosts = await db.users.find({ with: { posts: true } });
104
+ ```
107
105
 
108
- const testMigration = database.select("test_migration");
106
+ ## Features
109
107
 
110
- console.log("----------------------------------");
108
+ - **One schema, multiple databases** — MySQL, SQLite, and File drivers
109
+ - **Type-safe queries** — Full TypeScript inference for all operations
110
+ - **Smart caching** — Adaptive TTL cache with automatic invalidation
111
+ - **Migrations** — CLI and programmatic migration support
112
+ - **Schema sync** — Automatic table creation and column diffing
113
+ - **Relations** — Foreign key references with eager loading
111
114
 
112
- console.log(testMigration);
113
- ```
115
+ ## Links
114
116
 
115
- ## Functions
116
-
117
- | Function | Description |
118
- | ------------------------ | ---------------------------------------------- |
119
- | `dropAll` | To drop all data from a table |
120
- | `readTables` | To read the tables from the database |
121
- | `enableMigrations` | To enable migrations |
122
- | `createMigration` | To create a migration |
123
- | `createTable` | To create a table |
124
- | `deleteTable` | To delete a table |
125
- | `createTableIfNotExists` | To create a table if it does not exist |
126
- | `deleteTableIfExists` | To delete a table if it exists |
127
- | `renameTable` | To rename a table |
128
- | `addColumn` | To add a column to an already created table |
129
- | `deleteColumn` | To remove a column to an already created table |
130
- | `renameColumn` | To rename a column |
131
- | `insert` | To insert a data in the table |
132
- | `update` | To update a data in the table |
133
- | `select` | To search for information in a table |
134
- | `delete` | To delete a data from the table |
135
- | `getTableNames` | To get the names of all tables |
136
- | `getColumnNames` | To get the names of all columns |
137
- | `getRecordCount` | To get the number of records in a table |
117
+ - [Documentation](https://docs.hedystia.com/db/start)
118
+ - [GitHub](https://github.com/Hedystia/Hedystia)
119
+ - [Discord](https://hedystia.com/discord)
package/index.d.ts DELETED
@@ -1,65 +0,0 @@
1
- interface Records {
2
- [key: string]: unknown;
3
- }
4
- interface Table {
5
- columns: string[];
6
- records: Records[];
7
- }
8
- interface Migration {
9
- id: string;
10
- description: string;
11
- timestamp: number;
12
- applied: boolean;
13
- }
14
- export default class DataBase {
15
- private queue;
16
- private password;
17
- private filePath;
18
- private tables;
19
- private migrations;
20
- private migrationsEnabled;
21
- constructor(filePath: string, password: string);
22
- enableMigrations(): void;
23
- createMigration(migration: Omit<Migration, "applied">, migrationFn: () => Promise<void> | void): Promise<void>;
24
- createTable(tableName: string, columns?: string[]): void;
25
- createTableIfNotExists(tableName: string, columns: string[]): void;
26
- deleteTable(tableName: string): void;
27
- deleteTableIfExists(tableName: string): void;
28
- addColumn(tableName: string, column: string, defaultValue?: unknown): void;
29
- deleteColumn(tableName: string, column: string): void;
30
- insert(tableName: string, record: {
31
- [key: string]: unknown;
32
- }): void;
33
- update(tableName: string, query: {
34
- [key: string]: unknown;
35
- }, newData: {
36
- [key: string]: unknown;
37
- }): void;
38
- select(tableName: string, query?: {
39
- [key: string]: unknown;
40
- }): Records[];
41
- delete(tableName: string, query?: {
42
- [key: string]: unknown;
43
- }): void;
44
- readTables(): {
45
- [key: string]: Table;
46
- };
47
- dropAll(): void;
48
- renameTable(oldTableName: string, newTableName: string): void;
49
- renameColumn(tableName: string, oldColumnName: string, newColumnName: string): void;
50
- getTableNames(): string[];
51
- getColumnNames(tableName: string): string[];
52
- getRecordCount(tableName: string): number;
53
- private processQueue;
54
- private markMigrationAsApplied;
55
- private insertTable;
56
- private updateTable;
57
- private deleteFromTable;
58
- private dropAllData;
59
- private renameTableInDb;
60
- private renameColumnInDb;
61
- private saveToFile;
62
- private readFromFile;
63
- private evpBytesToKey;
64
- }
65
- export {};
package/index.js DELETED
@@ -1 +0,0 @@
1
- var m=Object.create;var{getPrototypeOf:y,defineProperty:l,getOwnPropertyNames:b,getOwnPropertyDescriptor:F}=Object,p=Object.prototype.hasOwnProperty;var g=(e,t,s)=>{s=e!=null?m(y(e)):{};let i=t||!e||!e.__esModule?l(s,"default",{value:e,enumerable:!0}):s;for(let r of b(e))if(!p.call(i,r))l(i,r,{get:()=>e[r],enumerable:!0});return i},f=new WeakMap,T=(e)=>{var t=f.get(e),s;if(t)return t;if(t=l({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")b(e).map((i)=>!p.call(t,i)&&l(t,i,{get:()=>e[i],enumerable:!(s=F(e,i))||s.enumerable}));return f.set(e,t),t};var k=(e,t)=>{for(var s in t)l(e,s,{get:t[s],enumerable:!0,configurable:!0,set:(i)=>t[s]=()=>i})};var q={};k(q,{default:()=>c});module.exports=T(q);var h=g(require("node:fs")),u=g(require("node:crypto"));class c{queue=[];password;filePath;tables={};migrations=[];migrationsEnabled=!1;constructor(e,t){this.tables={},this.filePath=e||"./database.ht",this.password=t,this.queue=[]}enableMigrations(){this.migrationsEnabled=!0,this.createTableIfNotExists("migrations",["id","description","timestamp","applied"])}async createMigration(e,t){if(!this.migrationsEnabled)throw new Error("Migrations are not enabled. Call enableMigrations() first.");this.readFromFile();let s=this.select("migrations",{id:e.id});if(!s[0]||!s[0].applied){if(this.migrations.push({...e,applied:!1}),this.insert("migrations",{...e,applied:!1}),this.queue.push({method:"migration",table:"migrations",record:{...e,applied:!1}}),this.queue.length===1)await this.processQueue(t)}}createTable(e,t=[]){if(this.readFromFile(),this.tables[e])throw new Error(`Table "${e}" already exists.`);this.tables[e]={columns:t,records:[]},this.saveToFile()}createTableIfNotExists(e,t){if(this.readFromFile(),!this.tables[e])this.tables[e]={columns:t,records:[]},this.saveToFile()}deleteTable(e){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);delete this.tables[e],this.saveToFile()}deleteTableIfExists(e){if(this.readFromFile(),this.tables[e])delete this.tables[e],this.saveToFile()}addColumn(e,t,s){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);if(this.tables[e].columns.includes(t))throw new Error(`Column "${t}" already exists in table "${e}".`);this.tables[e].columns.push(t);for(let i of this.tables[e].records)i[t]=s??null;this.saveToFile()}deleteColumn(e,t){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);if(!this.tables[e].columns.includes(t))throw new Error(`Column "${t}" does not exist in table "${e}".`);let s=this.tables[e].columns.indexOf(t);this.tables[e].columns.splice(s,1);for(let i of this.tables[e].records)delete i[t];this.saveToFile()}insert(e,t){if(this.queue.push({method:"insert",table:e,record:t}),this.queue.length===1)this.processQueue()}update(e,t,s){if(this.queue.push({method:"update",table:e,query:t,newData:s}),this.queue.length===1)this.processQueue()}select(e,t={}){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);return this.tables[e].records.filter((s)=>Object.entries(t).every(([i,r])=>s[i]===r))}delete(e,t={}){if(this.queue.push({method:"delete",table:e,query:t}),this.queue.length===1)this.processQueue()}readTables(){return this.readFromFile(),this.tables}dropAll(){if(this.queue.push({method:"dropAllData"}),this.queue.length===1)this.processQueue()}renameTable(e,t){if(this.queue.push({method:"renameTable",table:e,newTableName:t}),this.queue.length===1)this.processQueue()}renameColumn(e,t,s){if(this.queue.push({method:"renameColumn",table:e,column:t,newColumnName:s}),this.queue.length===1)this.processQueue()}getTableNames(){return this.readFromFile(),Object.keys(this.tables)}getColumnNames(e){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);return this.tables[e].columns}getRecordCount(e){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);return this.tables[e].records.length}async processQueue(e){let t=this.queue[0];switch(t.method){case"insert":if(!t.table)throw new Error("Table name is required.");this.insertTable(t.table,t.record);break;case"update":if(!t.table)throw new Error("Table name is required.");this.updateTable(t.table,t.query,t.newData);break;case"delete":if(!t.table)throw new Error("Table name is required.");this.deleteFromTable(t.table,t.query);break;case"dropAllData":this.dropAllData();break;case"migration":if(e)await e(),this.markMigrationAsApplied(t.record?.id);break;case"renameTable":if(!t.table||!t.newTableName)throw new Error("Old and new table names are required.");this.renameTableInDb(t.table,t.newTableName);break;case"renameColumn":if(!t.table||!t.column||!t.newColumnName)throw new Error("Table, old column, and new column names are required.");this.renameColumnInDb(t.table,t.column,t.newColumnName);break}}markMigrationAsApplied(e){this.readFromFile();let t=this.select("migrations",{id:e});if(t.length>0)this.updateTable("migrations",{id:e},{...t[0],applied:!0});if(this.queue.shift(),this.queue.length>0)this.processQueue()}insertTable(e,t){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);let s=this.tables[e],i={};for(let r of s.columns)i[r]=t[r]||null;if(s.records.push(i),this.saveToFile(),this.queue.shift(),this.queue.length>0)this.processQueue()}updateTable(e,t,s){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);let i=this.tables[e],r=i.records.map((n)=>{let a=Object.entries(s);for(let[o,d]of a)if(i.columns.includes(o)&&Object.entries(t).every(([w,v])=>n[w]===v))n[o]=d;return n});if(i.records=r,this.saveToFile(),this.queue.shift(),this.queue.length>0)this.processQueue()}deleteFromTable(e,t){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);if(this.tables[e].records=this.tables[e].records.filter((s)=>!Object.entries(t).every(([i,r])=>s[i]===r)),this.saveToFile(),this.queue.shift(),this.queue.length>0)this.processQueue()}dropAllData(){this.readFromFile();for(let e in this.tables)this.tables[e].records=[];if(this.saveToFile(),this.queue.shift(),this.queue.length>0)this.processQueue()}renameTableInDb(e,t){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);if(this.tables[t])throw new Error(`Table "${t}" already exists.`);if(this.tables[t]=this.tables[e],delete this.tables[e],this.saveToFile(),this.queue.shift(),this.queue.length>0)this.processQueue()}renameColumnInDb(e,t,s){if(this.readFromFile(),!this.tables[e])throw new Error(`Table "${e}" does not exist.`);if(!this.tables[e].columns.includes(t))throw new Error(`Column "${t}" does not exist in table "${e}".`);if(this.tables[e].columns.includes(s))throw new Error(`Column "${s}" already exists in table "${e}".`);let i=this.tables[e].columns.indexOf(t);this.tables[e].columns[i]=s;for(let r of this.tables[e].records)r[s]=r[t],delete r[t];if(this.saveToFile(),this.queue.shift(),this.queue.length>0)this.processQueue()}saveToFile(){if(!this.filePath.endsWith(".ht"))throw new Error(`File path must include '.ht': ${this.filePath}`);let e=JSON.stringify(this.tables),t=u.default.randomBytes(8),s=Buffer.from(this.password,"utf-8"),{key:i,iv:r}=this.evpBytesToKey(s,t,32,16),n=u.default.createCipheriv("aes-256-cbc",i,r),a=Buffer.concat([n.update(Buffer.from(e,"utf8")),n.final()]),o=Buffer.concat([Buffer.from("Salted__"),t,a]);h.default.writeFileSync(this.filePath,o.toString("base64"))}readFromFile(){if(!h.default.existsSync(this.filePath))return;try{let e=h.default.readFileSync(this.filePath,"utf8"),t=Buffer.from(e,"base64");if(t.length<16||t.subarray(0,8).toString()!=="Salted__")throw new Error("Invalid encrypted data format");let s=t.subarray(8,16),i=t.subarray(16),r=Buffer.from(this.password,"utf-8"),{key:n,iv:a}=this.evpBytesToKey(r,s,32,16),o=u.default.createDecipheriv("aes-256-cbc",n,a),d=Buffer.concat([o.update(i),o.final()]).toString("utf8");this.tables=JSON.parse(d)}catch(e){this.tables={}}}evpBytesToKey(e,t,s,i){let r=Buffer.alloc(0),n=Buffer.alloc(0),a=s+i;while(r.length<a){let o=u.default.createHash("md5");if(n.length>0)o.update(n);o.update(e),o.update(t),n=o.digest(),r=Buffer.concat([r,n])}return{key:r.subarray(0,s),iv:r.subarray(s,s+i)}}}