@iamkirbki/database-handler-core 2.0.0 → 3.0.0

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 (46) hide show
  1. package/dist/Database.d.ts +98 -0
  2. package/dist/Database.d.ts.map +1 -0
  3. package/dist/Database.js +0 -0
  4. package/dist/Query.d.ts +139 -0
  5. package/dist/Query.d.ts.map +1 -0
  6. package/dist/Query.js +0 -0
  7. package/dist/Record.d.ts +125 -0
  8. package/dist/Record.d.ts.map +1 -0
  9. package/dist/Record.js +0 -0
  10. package/dist/Schema.d.ts +14 -0
  11. package/dist/Schema.d.ts.map +1 -0
  12. package/dist/Schema.js +0 -0
  13. package/dist/Table.d.ts +158 -0
  14. package/dist/Table.d.ts.map +1 -0
  15. package/dist/Table.js +0 -0
  16. package/dist/abstract/Model.d.ts +513 -0
  17. package/dist/abstract/Model.d.ts.map +1 -0
  18. package/dist/abstract/Model.js +0 -0
  19. package/dist/abstract/User.d.ts +8 -0
  20. package/dist/abstract/User.d.ts.map +1 -0
  21. package/dist/abstract/User.js +0 -0
  22. package/dist/helpers/QueryStatementBuilder.d.ts +333 -0
  23. package/dist/helpers/QueryStatementBuilder.d.ts.map +1 -0
  24. package/dist/helpers/QueryStatementBuilder.js +0 -0
  25. package/dist/helpers/Validator.d.ts +210 -0
  26. package/dist/helpers/Validator.d.ts.map +1 -0
  27. package/dist/helpers/Validator.js +0 -0
  28. package/dist/index.d.ts +56 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +5 -1
  31. package/dist/interfaces/IDatabaseAdapter.d.ts +11 -0
  32. package/dist/interfaces/IDatabaseAdapter.d.ts.map +1 -0
  33. package/dist/interfaces/IDatabaseAdapter.js +0 -0
  34. package/dist/interfaces/IStatementAdapter.d.ts +7 -0
  35. package/dist/interfaces/IStatementAdapter.d.ts.map +1 -0
  36. package/dist/interfaces/IStatementAdapter.js +0 -0
  37. package/dist/types/index.d.ts +6 -0
  38. package/dist/types/index.d.ts.map +1 -0
  39. package/dist/types/index.js +0 -0
  40. package/dist/types/query.d.ts +14 -0
  41. package/dist/types/query.d.ts.map +1 -0
  42. package/dist/types/query.js +0 -0
  43. package/dist/types/table.d.ts +23 -0
  44. package/dist/types/table.d.ts.map +1 -0
  45. package/dist/types/table.js +0 -0
  46. package/package.json +1 -1
@@ -0,0 +1,333 @@
1
+ import { DefaultQueryOptions, QueryOptions, QueryParameters, Join } from "../types/index";
2
+ import Table from "Table";
3
+ /**
4
+ * QueryStatementBuilder - Utility class for building SQL query strings
5
+ *
6
+ * Provides static methods to construct SQL statements in a consistent, safe manner.
7
+ * All methods use named parameters (@fieldName syntax) for better-sqlite3 compatibility.
8
+ *
9
+ * Features:
10
+ * - Consistent query building pattern using array concatenation
11
+ * - Support for SELECT, INSERT, UPDATE, DELETE, and COUNT operations
12
+ * - JOIN support with nested join capabilities
13
+ * - WHERE clause building with AND conditions
14
+ * - Query options (ORDER BY, LIMIT, OFFSET)
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * // Build a SELECT query
19
+ * const query = QueryStatementBuilder.BuildSelect(usersTable, {
20
+ * select: 'id, name, email',
21
+ * where: { status: 'active' },
22
+ * orderBy: 'created_at DESC',
23
+ * limit: 10
24
+ * });
25
+ * // Result: "SELECT id, name, email FROM users WHERE status = @status ORDER BY created_at DESC LIMIT 10"
26
+ *
27
+ * // Build an INSERT query
28
+ * const insertQuery = QueryStatementBuilder.BuildInsert(usersTable, {
29
+ * name: 'John',
30
+ * email: 'john@example.com'
31
+ * });
32
+ * // Result: "INSERT INTO users (name, email) VALUES (@name, @email)"
33
+ * ```
34
+ */
35
+ export default class QueryStatementBuilder {
36
+ /**
37
+ * Build a SELECT SQL statement with optional filtering, ordering, and pagination
38
+ *
39
+ * @param table - The table to select from
40
+ * @param options - Query options including select columns, where conditions, orderBy, limit, offset
41
+ * @returns Complete SELECT SQL statement string
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * // Select all columns
46
+ * const query = QueryStatementBuilder.BuildSelect(usersTable);
47
+ * // "SELECT * FROM users"
48
+ *
49
+ * // Select specific columns with filtering
50
+ * const query = QueryStatementBuilder.BuildSelect(usersTable, {
51
+ * select: 'id, name, email',
52
+ * where: { status: 'active', age: 25 },
53
+ * orderBy: 'created_at DESC',
54
+ * limit: 10,
55
+ * offset: 20
56
+ * });
57
+ * // "SELECT id, name, email FROM users WHERE status = @status AND age = @age ORDER BY created_at DESC LIMIT 10 OFFSET 20"
58
+ * ```
59
+ */
60
+ static BuildSelect(table: Table, options?: DefaultQueryOptions & QueryOptions): string;
61
+ /**
62
+ * Build an INSERT SQL statement with named parameter placeholders
63
+ *
64
+ * @param table - The table to insert into
65
+ * @param record - Object containing column names and their placeholder values
66
+ * @returns Complete INSERT SQL statement string with @fieldName placeholders
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const query = QueryStatementBuilder.BuildInsert(usersTable, {
71
+ * name: 'John',
72
+ * email: 'john@example.com',
73
+ * age: 30
74
+ * });
75
+ * // "INSERT INTO users (name, email, age) VALUES (@name, @email, @age)"
76
+ *
77
+ * // Note: The actual values will be bound separately using the Parameters object
78
+ * ```
79
+ */
80
+ static BuildInsert(table: Table, record: QueryParameters): string;
81
+ /**
82
+ * Build an UPDATE SQL statement with SET clause and WHERE conditions
83
+ *
84
+ * @param table - The table to update
85
+ * @param record - Object containing columns to update with their placeholder values
86
+ * @param where - Object containing WHERE conditions for targeting specific rows
87
+ * @returns Complete UPDATE SQL statement string with @fieldName placeholders
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * const query = QueryStatementBuilder.BuildUpdate(
92
+ * usersTable,
93
+ * { name: 'John Doe', age: 31 },
94
+ * { id: 1 }
95
+ * );
96
+ * // "UPDATE users SET name = @name, age = @age WHERE id = @id"
97
+ *
98
+ * // Multiple WHERE conditions
99
+ * const query = QueryStatementBuilder.BuildUpdate(
100
+ * usersTable,
101
+ * { status: 'inactive' },
102
+ * { status: 'active', last_login: '2023-01-01' }
103
+ * );
104
+ * // "UPDATE users SET status = @status WHERE status = @status AND last_login = @last_login"
105
+ * ```
106
+ */
107
+ static BuildUpdate(table: Table, record: QueryParameters, where: QueryParameters): string;
108
+ /**
109
+ * Build a DELETE SQL statement with WHERE conditions
110
+ *
111
+ * @param table - The table to delete from
112
+ * @param where - Object containing WHERE conditions for targeting specific rows to delete
113
+ * @returns Complete DELETE SQL statement string with @fieldName placeholders
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const query = QueryStatementBuilder.BuildDelete(usersTable, { id: 1 });
118
+ * // "DELETE FROM users WHERE id = @id"
119
+ *
120
+ * // Multiple WHERE conditions
121
+ * const query = QueryStatementBuilder.BuildDelete(usersTable, {
122
+ * status: 'deleted',
123
+ * last_login: '2020-01-01'
124
+ * });
125
+ * // "DELETE FROM users WHERE status = @status AND last_login = @last_login"
126
+ * ```
127
+ */
128
+ static BuildDelete(table: Table, where: QueryParameters): string;
129
+ /**
130
+ * Build a COUNT SQL statement to count rows, optionally with WHERE conditions
131
+ *
132
+ * @param table - The table to count rows from
133
+ * @param where - Optional object containing WHERE conditions to filter counted rows
134
+ * @returns Complete COUNT SQL statement string with @fieldName placeholders
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * // Count all rows
139
+ * const query = QueryStatementBuilder.BuildCount(usersTable);
140
+ * // "SELECT COUNT(*) as count FROM users"
141
+ *
142
+ * // Count with conditions
143
+ * const query = QueryStatementBuilder.BuildCount(usersTable, {
144
+ * status: 'active',
145
+ * age: 25
146
+ * });
147
+ * // "SELECT COUNT(*) as count FROM users WHERE status = @status AND age = @age"
148
+ * ```
149
+ */
150
+ static BuildCount(table: Table, where?: QueryParameters): string;
151
+ /**
152
+ * Build a WHERE clause from parameter conditions (helper method)
153
+ *
154
+ * Joins multiple conditions with AND operator.
155
+ * Returns empty string if no conditions are provided.
156
+ *
157
+ * @param where - Optional object containing WHERE conditions
158
+ * @returns WHERE clause string with @fieldName placeholders, or empty string if no conditions
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * // Single condition
163
+ * const whereClause = QueryStatementBuilder.BuildWhere({ id: 1 });
164
+ * // "WHERE id = @id"
165
+ *
166
+ * // Multiple conditions (joined with AND)
167
+ * const whereClause = QueryStatementBuilder.BuildWhere({
168
+ * status: 'active',
169
+ * age: 25,
170
+ * role: 'admin'
171
+ * });
172
+ * // "WHERE status = @status AND age = @age AND role = @role"
173
+ *
174
+ * // No conditions
175
+ * const whereClause = QueryStatementBuilder.BuildWhere();
176
+ * // ""
177
+ * ```
178
+ */
179
+ static BuildWhere(where?: QueryParameters): string;
180
+ /**
181
+ * Build a SELECT statement with JOIN operations (INNER, LEFT, RIGHT, FULL)
182
+ *
183
+ * Supports single or multiple joins, including nested joins.
184
+ * Combines the base SELECT with JOIN clauses and query options.
185
+ * The join type (INNER, LEFT, RIGHT, FULL) is specified in each Join object.
186
+ *
187
+ * @param fromTable - The primary table to select from
188
+ * @param joins - Single Join object or array of Join objects defining the join operations
189
+ * @param options - Query options including select columns, orderBy, limit, offset
190
+ * @returns Complete SELECT statement with JOIN clauses
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * // Single INNER JOIN
195
+ * const query = QueryStatementBuilder.BuildJoin(
196
+ * usersTable,
197
+ * { fromTable: ordersTable, joinType: 'INNER', on: { user_id: 'id' } },
198
+ * { select: 'users.*, orders.total' }
199
+ * );
200
+ * // "SELECT users.*, orders.total FROM users INNER JOIN orders ON users.id = orders.user_id"
201
+ *
202
+ * // Multiple joins with different types
203
+ * const query = QueryStatementBuilder.BuildJoin(
204
+ * usersTable,
205
+ * [
206
+ * { fromTable: ordersTable, joinType: 'INNER', on: { user_id: 'id' } },
207
+ * { fromTable: addressesTable, joinType: 'LEFT', on: { address_id: 'id' } }
208
+ * ],
209
+ * { orderBy: 'users.created_at DESC', limit: 10 }
210
+ * );
211
+ *
212
+ * // Nested JOIN
213
+ * const query = QueryStatementBuilder.BuildJoin(
214
+ * usersTable,
215
+ * {
216
+ * fromTable: ordersTable,
217
+ * joinType: 'INNER',
218
+ * on: { user_id: 'id' },
219
+ * join: { fromTable: productsTable, joinType: 'INNER', on: { product_id: 'id' } }
220
+ * }
221
+ * );
222
+ * ```
223
+ */
224
+ static BuildJoin(fromTable: Table, joins: Join | Join[], options?: DefaultQueryOptions & QueryOptions): string;
225
+ /**
226
+ * Build JOIN clause(s) recursively (helper method)
227
+ *
228
+ * Processes single or multiple join definitions and handles nested joins.
229
+ * Each join includes the JOIN clause (INNER, LEFT, RIGHT, FULL) and ON conditions.
230
+ *
231
+ * @param fromTable - The table being joined from (for ON clause context)
232
+ * @param joins - Single Join object or array of Join objects
233
+ * @returns JOIN clause(s) as a string
234
+ *
235
+ * @example
236
+ * ```typescript
237
+ * // Single INNER JOIN
238
+ * const joinClause = QueryStatementBuilder.BuildJoinPart(
239
+ * usersTable,
240
+ * { fromTable: ordersTable, joinType: 'INNER', on: { user_id: 'id' } }
241
+ * );
242
+ * // "INNER JOIN orders ON users.id = orders.user_id"
243
+ *
244
+ * // LEFT JOIN
245
+ * const joinClause = QueryStatementBuilder.BuildJoinPart(
246
+ * usersTable,
247
+ * { fromTable: profilesTable, joinType: 'LEFT', on: { profile_id: 'id' } }
248
+ * );
249
+ * // "LEFT JOIN profiles ON users.id = profiles.profile_id"
250
+ *
251
+ * // Nested join
252
+ * const joinClause = QueryStatementBuilder.BuildJoinPart(
253
+ * usersTable,
254
+ * {
255
+ * fromTable: ordersTable,
256
+ * joinType: 'INNER',
257
+ * on: { user_id: 'id' },
258
+ * join: { fromTable: productsTable, joinType: 'INNER', on: { product_id: 'id' } }
259
+ * }
260
+ * );
261
+ * // "INNER JOIN orders ON users.id = orders.user_id INNER JOIN products ON orders.id = products.product_id"
262
+ * ```
263
+ */
264
+ static BuildJoinPart(fromTable: Table, joins: Join | Join[]): string;
265
+ /**
266
+ * Build ON clause for JOIN operations (helper method)
267
+ *
268
+ * Creates ON conditions for join operations.
269
+ * Compares the foreign key column in the joined table with the primary key in the source table.
270
+ * Multiple conditions are joined with AND operator.
271
+ *
272
+ * @param table - The source table (left side of the join)
273
+ * @param joinTable - The table being joined (right side of the join)
274
+ * @param on - QueryParameters object where key is the foreign key in joinTable and value is the primary key in table
275
+ * @returns ON clause string for JOIN operations
276
+ *
277
+ * @example
278
+ * ```typescript
279
+ * // Single ON condition
280
+ * // Key: column in joinTable (orders), Value: column in table (users)
281
+ * const onClause = QueryStatementBuilder.BuildJoinOnPart(
282
+ * usersTable,
283
+ * ordersTable,
284
+ * { user_id: 'id' }
285
+ * );
286
+ * // "ON users.id = orders.user_id"
287
+ *
288
+ * // Multiple ON conditions
289
+ * const onClause = QueryStatementBuilder.BuildJoinOnPart(
290
+ * usersTable,
291
+ * ordersTable,
292
+ * [{ user_id: 'id' }, { company_id: 'company_id' }]
293
+ * );
294
+ * // "ON users.id = orders.user_id AND users.company_id = orders.company_id"
295
+ * ```
296
+ */
297
+ static BuildJoinOnPart(table: Table, joinTable: Table, on: QueryParameters | QueryParameters[]): string;
298
+ /**
299
+ * Build query options clause (ORDER BY, LIMIT, OFFSET) (helper method)
300
+ *
301
+ * Processes query options and builds the corresponding SQL clauses.
302
+ * Returns empty string if no options are provided.
303
+ *
304
+ * @param options - Object containing orderBy, limit, and/or offset options
305
+ * @returns Query options clause as a string
306
+ *
307
+ * @example
308
+ * ```typescript
309
+ * // All options
310
+ * const optionsClause = QueryStatementBuilder.BuildQueryOptions({
311
+ * orderBy: 'created_at DESC',
312
+ * limit: 10,
313
+ * offset: 20
314
+ * });
315
+ * // "ORDER BY created_at DESC LIMIT 10 OFFSET 20"
316
+ *
317
+ * // Just ordering
318
+ * const optionsClause = QueryStatementBuilder.BuildQueryOptions({
319
+ * orderBy: 'name ASC'
320
+ * });
321
+ * // "ORDER BY name ASC"
322
+ *
323
+ * // Pagination only
324
+ * const optionsClause = QueryStatementBuilder.BuildQueryOptions({
325
+ * limit: 25,
326
+ * offset: 50
327
+ * });
328
+ * // "LIMIT 25 OFFSET 50"
329
+ * ```
330
+ */
331
+ static BuildQueryOptions(options: QueryOptions): string;
332
+ }
333
+ //# sourceMappingURL=QueryStatementBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryStatementBuilder.d.ts","sourceRoot":"","sources":["../../src/helpers/QueryStatementBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC1F,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACtC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;WACW,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,YAAY,GAAG,MAAM;IAY7F;;;;;;;;;;;;;;;;;;OAkBG;WACW,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM;IAYxE;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;WACW,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM;IAWhG;;;;;;;;;;;;;;;;;;;OAmBG;WACW,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM;IASvE;;;;;;;;;;;;;;;;;;;;OAoBG;WACW,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,MAAM;IAQvE;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;WACW,UAAU,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,MAAM;IAYzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;WACW,SAAS,CACnB,SAAS,EAAE,KAAK,EAChB,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,EACpB,OAAO,CAAC,EAAE,mBAAmB,GAAG,YAAY;IAYhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;WACW,aAAa,CACvB,SAAS,EAAE,KAAK,EAChB,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GACrB,MAAM;IAeT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;WACW,eAAe,CACzB,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,KAAK,EAChB,EAAE,EAAE,eAAe,GAAG,eAAe,EAAE,GACxC,MAAM;IAWT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;WACW,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM;CAiBjE"}
File without changes
@@ -0,0 +1,210 @@
1
+ import { QueryParameters, TableColumnInfo } from "../types/index";
2
+ /**
3
+ * Validator class for validating table names, column names, column types, SQL queries, and query parameters
4
+ *
5
+ * Provides static methods to ensure data integrity and prevent SQL injection attacks by:
6
+ * - Validating table and column naming conventions
7
+ * - Checking column type compatibility with SQLite standards
8
+ * - Detecting SQL injection patterns in queries
9
+ * - Verifying parameter types match column types
10
+ * - Enforcing NOT NULL constraints
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Validate a table name
15
+ * Validator.ValidateTableName('users'); // OK
16
+ * Validator.ValidateTableName('invalid-name'); // throws Error
17
+ *
18
+ * // Validate a column type
19
+ * Validator.ValidateColumnType('TEXT NOT NULL'); // OK
20
+ * Validator.ValidateColumnType('INVALID_TYPE'); // throws Error
21
+ *
22
+ * // Validate a query for SQL injection
23
+ * Validator.ValidateQuery('SELECT * FROM users WHERE id = @id', columnInfo); // OK
24
+ * Validator.ValidateQuery('SELECT * FROM users; DROP TABLE users', columnInfo); // throws Error
25
+ * ```
26
+ */
27
+ export default class Validator {
28
+ /**
29
+ * List of valid SQLite column types
30
+ * Includes numeric, text, binary, date/time types and compatibility types for other SQL dialects
31
+ */
32
+ private static readonly validTypes;
33
+ /**
34
+ * List of SQL keywords that are valid in column type definitions
35
+ * These keywords are stripped when validating the base column type
36
+ */
37
+ private static readonly sqlKeywords;
38
+ /**
39
+ * Validates a table name according to SQLite naming conventions
40
+ *
41
+ * Rules:
42
+ * - Must be a non-empty string
43
+ * - Cannot contain commas
44
+ * - Must only contain letters, numbers, and underscores
45
+ *
46
+ * @param name - The table name to validate
47
+ * @throws Error if the table name is invalid
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * Validator.ValidateTableName('users'); // OK
52
+ * Validator.ValidateTableName('user_accounts'); // OK
53
+ * Validator.ValidateTableName('users123'); // OK
54
+ * Validator.ValidateTableName('invalid-name'); // throws Error
55
+ * Validator.ValidateTableName(''); // throws Error
56
+ * ```
57
+ */
58
+ static ValidateTableName(name: string): void;
59
+ /**
60
+ * Validates a column name according to SQLite naming conventions
61
+ *
62
+ * Rules:
63
+ * - Must be a non-empty string
64
+ * - Cannot contain commas
65
+ * - Must only contain letters, numbers, and underscores
66
+ *
67
+ * @param name - The column name to validate
68
+ * @throws Error if the column name is invalid
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * Validator.ValidateColumnName('email'); // OK
73
+ * Validator.ValidateColumnName('user_id'); // OK
74
+ * Validator.ValidateColumnName('created_at'); // OK
75
+ * Validator.ValidateColumnName('invalid-name'); // throws Error
76
+ * Validator.ValidateColumnName(''); // throws Error
77
+ * ```
78
+ */
79
+ static ValidateColumnName(name: string): void;
80
+ /**
81
+ * Generic name validation for tables and columns
82
+ *
83
+ * Rules:
84
+ * - Must be a non-empty string
85
+ * - Cannot contain commas
86
+ * - Must only contain letters, numbers, and underscores
87
+ *
88
+ * @param name - The table/column name to validate
89
+ * @param type - The type, either table or column
90
+ * @throws Error if the name is invalid
91
+ */
92
+ private static ValidateName;
93
+ /**
94
+ * Validates a column type definition against SQLite type standards
95
+ *
96
+ * Strips SQL keywords (NOT NULL, PRIMARY KEY, etc.) and length specifications
97
+ * before checking if the base type is valid. Supports all SQLite types and
98
+ * common types from other SQL dialects for compatibility.
99
+ *
100
+ * @param type - The column type definition to validate (e.g., "TEXT NOT NULL", "VARCHAR(255)")
101
+ * @throws Error if the column type is invalid
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * Validator.ValidateColumnType('TEXT'); // OK
106
+ * Validator.ValidateColumnType('INTEGER NOT NULL'); // OK
107
+ * Validator.ValidateColumnType('VARCHAR(255)'); // OK
108
+ * Validator.ValidateColumnType('TEXT PRIMARY KEY'); // OK
109
+ * Validator.ValidateColumnType('INVALID_TYPE'); // throws Error
110
+ * ```
111
+ */
112
+ static ValidateColumnType(type: string): void;
113
+ /**
114
+ * Validates an SQL query for security and correctness
115
+ *
116
+ * Security checks:
117
+ * - Detects SQL injection attempts (semicolon followed by DROP, DELETE, UPDATE, INSERT, ALTER)
118
+ * - Ensures all field references (@fieldName) exist in the table schema
119
+ *
120
+ * Correctness checks:
121
+ * - Verifies all required (NOT NULL) fields are provided in INSERT queries
122
+ * - Validates query is a non-empty string
123
+ *
124
+ * @param query - The SQL query string to validate
125
+ * @param TableColumnInformation - Array of column metadata from the table schema
126
+ * @throws Error if the query contains forbidden operations, references unknown fields, or missing required fields
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const columnInfo = [
131
+ * { name: 'id', type: 'INTEGER', notnull: 1 },
132
+ * { name: 'name', type: 'TEXT', notnull: 1 },
133
+ * { name: 'email', type: 'TEXT', notnull: 0 }
134
+ * ];
135
+ *
136
+ * // Valid queries
137
+ * Validator.ValidateQuery('SELECT * FROM users WHERE id = @id', columnInfo); // OK
138
+ * Validator.ValidateQuery('INSERT INTO users (name, email) VALUES (@name, @email)', columnInfo); // OK
139
+ *
140
+ * // Invalid queries
141
+ * Validator.ValidateQuery('SELECT * FROM users; DROP TABLE users', columnInfo); // throws Error - SQL injection
142
+ * Validator.ValidateQuery('SELECT * FROM users WHERE @nonexistent = 1', columnInfo); // throws Error - unknown field
143
+ * Validator.ValidateQuery('INSERT INTO users (email) VALUES (@email)', columnInfo); // throws Error - missing required field 'name'
144
+ * ```
145
+ */
146
+ static ValidateQuery(query: string, TableColumnInformation: TableColumnInfo[]): void;
147
+ /**
148
+ * Validates query parameters against table schema
149
+ *
150
+ * Checks performed:
151
+ * - Each parameter key must match a column in the table
152
+ * - NOT NULL columns cannot receive null or undefined values
153
+ * - Parameter types must match their corresponding column types
154
+ * - All field references in the query must have corresponding parameters
155
+ *
156
+ * @param query - The SQL query string containing field references
157
+ * @param parameters - Object mapping parameter names to values
158
+ * @param TableColumnInformation - Array of column metadata from the table schema
159
+ * @throws Error if parameters don't match schema, have wrong types, or violate NOT NULL constraints
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * const columnInfo = [
164
+ * { name: 'id', type: 'INTEGER', notnull: 1 },
165
+ * { name: 'name', type: 'TEXT', notnull: 1 },
166
+ * { name: 'age', type: 'INTEGER', notnull: 0 }
167
+ * ];
168
+ *
169
+ * const query = 'INSERT INTO users (name, age) VALUES (@name, @age)';
170
+ *
171
+ * // Valid parameters
172
+ * Validator.ValidateQueryParameters(query, { name: 'John', age: 30 }, columnInfo); // OK
173
+ * Validator.ValidateQueryParameters(query, { name: 'Jane', age: null }, columnInfo); // OK - age is nullable
174
+ *
175
+ * // Invalid parameters
176
+ * Validator.ValidateQueryParameters(query, { name: null, age: 30 }, columnInfo); // throws Error - name is NOT NULL
177
+ * Validator.ValidateQueryParameters(query, { name: 'John', age: 'thirty' }, columnInfo); // throws Error - wrong type
178
+ * Validator.ValidateQueryParameters(query, { name: 'John' }, columnInfo); // throws Error - missing @age parameter
179
+ * Validator.ValidateQueryParameters(query, { name: 'John', age: 30, extra: 'value' }, columnInfo); // throws Error - extra is not a column
180
+ * ```
181
+ */
182
+ static ValidateQueryParameters(query: string, parameters: QueryParameters, TableColumnInformation: TableColumnInfo[]): void;
183
+ /**
184
+ * Compares a column type with a JavaScript parameter type for compatibility
185
+ *
186
+ * Type mappings:
187
+ * - TEXT/CHAR types → string
188
+ * - INTEGER/INT types → number
189
+ * - REAL/FLOAT/DOUBLE types → number
190
+ * - BOOLEAN types → boolean
191
+ * - BLOB types → object (Buffer/Uint8Array)
192
+ * - UUID → string (with format validation)
193
+ *
194
+ * @param columnType - The SQLite column type from the schema
195
+ * @param parameterType - The JavaScript typeof value for the parameter
196
+ * @returns true if the types are compatible, false otherwise
197
+ *
198
+ * @example
199
+ * ```typescript
200
+ * Validator.CompareTypes('TEXT', 'string'); // true
201
+ * Validator.CompareTypes('INTEGER', 'number'); // true
202
+ * Validator.CompareTypes('VARCHAR(255)', 'string'); // true
203
+ * Validator.CompareTypes('REAL', 'number'); // true
204
+ * Validator.CompareTypes('TEXT', 'number'); // false
205
+ * Validator.CompareTypes('INTEGER', 'string'); // false
206
+ * ```
207
+ */
208
+ static CompareTypes(columnType?: string, parameterType?: string): boolean;
209
+ }
210
+ //# sourceMappingURL=Validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Validator.d.ts","sourceRoot":"","sources":["../../src/helpers/Validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,OAAO,OAAO,SAAS;IAC1B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAkBhC;IAEF;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAWjC;IAEF;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI5C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI7C;;;;;;;;;;;MAWE;IACF,OAAO,CAAC,MAAM,CAAC,YAAY;IAY3B;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAgB7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,eAAe,EAAE,GAAG,IAAI;IA0CpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH,MAAM,CAAC,uBAAuB,CAC1B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,eAAe,EAC3B,sBAAsB,EAAE,eAAe,EAAE,GAC1C,IAAI;IAkCP;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO;CAoC5E"}
File without changes
@@ -0,0 +1,56 @@
1
+ /**
2
+ * kirbkis-bettersqlite3-handler
3
+ * A TypeScript wrapper for better-sqlite3 with type-safe operations and parameter validation
4
+ *
5
+ * Features:
6
+ * - Type-safe database operations with TypeScript generics
7
+ * - Automatic parameter validation against table schema
8
+ * - SQL injection prevention through query validation
9
+ * - Named parameters using @fieldName syntax
10
+ * - Record-based API for easy updates and deletes
11
+ * - Transaction support for atomic operations
12
+ * - Comprehensive error messages for debugging
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { Database } from 'kirbkis-bettersqlite3-handler';
17
+ *
18
+ * // Create/open database
19
+ * const db = new Database('./myapp.db');
20
+ *
21
+ * // Create table
22
+ * const users = db.CreateTable('users', {
23
+ * id: 'INTEGER PRIMARY KEY AUTOINCREMENT',
24
+ * name: 'TEXT NOT NULL',
25
+ * email: 'TEXT UNIQUE',
26
+ * age: 'INTEGER'
27
+ * });
28
+ *
29
+ * // Insert data
30
+ * users.Insert({ name: 'John', email: 'john@example.com', age: 30 });
31
+ *
32
+ * // Query data
33
+ * const activeUsers = users.Records({ where: { age: 30 } });
34
+ *
35
+ * // Update record
36
+ * const user = users.Record({ where: { id: 1 } });
37
+ * user?.Update({ age: 31 });
38
+ *
39
+ * // Custom query
40
+ * const query = db.Query(users, 'SELECT * FROM users WHERE age > @minAge');
41
+ * query.Parameters = { minAge: 25 };
42
+ * const results = query.All();
43
+ * ```
44
+ *
45
+ * @packageDocumentation
46
+ */
47
+ import Database from "./Database";
48
+ import Model from "./abstract/Model";
49
+ import IDatabaseAdapter from "./interfaces/IDatabaseAdapter";
50
+ import IStatementAdapter from "./interfaces/IStatementAdapter";
51
+ import Table from "./Table";
52
+ import Query from "./Query";
53
+ import Record from "./Record";
54
+ export { Database, Model, IDatabaseAdapter, IStatementAdapter, Table, Query, Record };
55
+ export * from "./types/index";
56
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,MAAM,kBAAkB,CAAC;AACrC,OAAO,gBAAgB,MAAM,+BAA+B,CAAC;AAC7D,OAAO,iBAAiB,MAAM,gCAAgC,CAAC;AAC/D,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACtF,cAAc,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -46,4 +46,8 @@
46
46
  */
47
47
  import Database from "./Database";
48
48
  import Model from "./abstract/Model";
49
- export { Database, Model };
49
+ import Table from "./Table";
50
+ import Query from "./Query";
51
+ import Record from "./Record";
52
+ export { Database, Model, Table, Query, Record };
53
+ export * from "./types/index";
@@ -0,0 +1,11 @@
1
+ import { TableColumnInfo } from '@core/types/table';
2
+ import IStatementAdapter from './IStatementAdapter';
3
+ export default interface IDatabaseAdapter {
4
+ connect(params: unknown): Promise<void>;
5
+ prepare(query: string): Promise<IStatementAdapter>;
6
+ exec(query: string): Promise<void>;
7
+ transaction(fn: (items: any[]) => void): Promise<Function>;
8
+ tableColumnInformation(tableName: string): Promise<TableColumnInfo[]>;
9
+ close(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=IDatabaseAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IDatabaseAdapter.d.ts","sourceRoot":"","sources":["../../src/interfaces/IDatabaseAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AAEpD,MAAM,CAAC,OAAO,WAAW,gBAAgB;IACrC,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
File without changes
@@ -0,0 +1,7 @@
1
+ export default interface IStatementAdapter {
2
+ run(parameters?: object): Promise<unknown>;
3
+ all(parameters?: object): Promise<unknown[]>;
4
+ get(parameters?: object): Promise<unknown | undefined>;
5
+ runSync?(parameters?: object): unknown;
6
+ }
7
+ //# sourceMappingURL=IStatementAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IStatementAdapter.d.ts","sourceRoot":"","sources":["../../src/interfaces/IStatementAdapter.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,WAAW,iBAAiB;IACtC,GAAG,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,GAAG,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,GAAG,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAEvD,OAAO,CAAC,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1C"}
File without changes
@@ -0,0 +1,6 @@
1
+ export type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
2
+ [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
3
+ }[Keys];
4
+ export * from './query';
5
+ export * from './table';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,IAC3D,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,GAC7B;KACG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;CAC3E,CAAC,IAAI,CAAC,CAAA;AAEX,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}