@onurege3467/zerohelper 6.0.2 → 6.2.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.
@@ -0,0 +1,151 @@
1
+ {
2
+ "excluded_patterns": [
3
+ ".git",
4
+ ".gitignore",
5
+ "gradle",
6
+ "gradlew",
7
+ "gradlew.*",
8
+ "node_modules",
9
+ ".snapshots",
10
+ ".idea",
11
+ ".vscode",
12
+ "*.log",
13
+ "*.tmp",
14
+ "target",
15
+ "dist",
16
+ "build",
17
+ ".DS_Store",
18
+ "*.bak",
19
+ "*.swp",
20
+ "*.swo",
21
+ "*.lock",
22
+ "*.iml",
23
+ "coverage",
24
+ "*.min.js",
25
+ "*.min.css",
26
+ "__pycache__",
27
+ ".marketing",
28
+ ".env",
29
+ ".env.*",
30
+ "*.jpg",
31
+ "*.jpeg",
32
+ "*.png",
33
+ "*.gif",
34
+ "*.bmp",
35
+ "*.tiff",
36
+ "*.ico",
37
+ "*.svg",
38
+ "*.webp",
39
+ "*.psd",
40
+ "*.ai",
41
+ "*.eps",
42
+ "*.indd",
43
+ "*.raw",
44
+ "*.cr2",
45
+ "*.nef",
46
+ "*.mp4",
47
+ "*.mov",
48
+ "*.avi",
49
+ "*.wmv",
50
+ "*.flv",
51
+ "*.mkv",
52
+ "*.webm",
53
+ "*.m4v",
54
+ "*.wfp",
55
+ "*.prproj",
56
+ "*.aep",
57
+ "*.psb",
58
+ "*.xcf",
59
+ "*.sketch",
60
+ "*.fig",
61
+ "*.xd",
62
+ "*.db",
63
+ "*.sqlite",
64
+ "*.sqlite3",
65
+ "*.mdb",
66
+ "*.accdb",
67
+ "*.frm",
68
+ "*.myd",
69
+ "*.myi",
70
+ "*.ibd",
71
+ "*.dbf",
72
+ "*.rdb",
73
+ "*.aof",
74
+ "*.pdb",
75
+ "*.sdb",
76
+ "*.s3db",
77
+ "*.ddb",
78
+ "*.db-shm",
79
+ "*.db-wal",
80
+ "*.sqlitedb",
81
+ "*.sql.gz",
82
+ "*.bak.sql",
83
+ "dump.sql",
84
+ "dump.rdb",
85
+ "*.vsix",
86
+ "*.jar",
87
+ "*.war",
88
+ "*.ear",
89
+ "*.zip",
90
+ "*.tar",
91
+ "*.tar.gz",
92
+ "*.tgz",
93
+ "*.rar",
94
+ "*.7z",
95
+ "*.exe",
96
+ "*.dll",
97
+ "*.so",
98
+ "*.dylib",
99
+ "*.app",
100
+ "*.dmg",
101
+ "*.iso",
102
+ "*.msi",
103
+ "*.deb",
104
+ "*.rpm",
105
+ "*.apk",
106
+ "*.aab",
107
+ "*.ipa",
108
+ "*.pkg",
109
+ "*.nupkg",
110
+ "*.snap",
111
+ "*.whl",
112
+ "*.gem",
113
+ "*.pyc",
114
+ "*.pyo",
115
+ "*.pyd",
116
+ "*.class",
117
+ "*.o",
118
+ "*.obj",
119
+ "*.lib",
120
+ "*.a",
121
+ "*.map",
122
+ ".npmrc"
123
+ ],
124
+ "default": {
125
+ "default_prompt": "Enter your prompt here",
126
+ "default_include_all_files": false,
127
+ "default_include_entire_project_structure": true
128
+ },
129
+ "included_patterns": [
130
+ "build.gradle",
131
+ "settings.gradle",
132
+ "gradle.properties",
133
+ "pom.xml",
134
+ "Makefile",
135
+ "CMakeLists.txt",
136
+ "package.json",
137
+ "requirements.txt",
138
+ "Pipfile",
139
+ "Gemfile",
140
+ "composer.json",
141
+ ".editorconfig",
142
+ ".eslintrc.json",
143
+ ".eslintrc.js",
144
+ ".prettierrc",
145
+ ".babelrc",
146
+ ".dockerignore",
147
+ ".gitattributes",
148
+ ".stylelintrc",
149
+ ".npmrc"
150
+ ]
151
+ }
@@ -0,0 +1,11 @@
1
+ # Snapshots Directory
2
+
3
+ This directory contains snapshots of your code for AI interactions. Each snapshot is a markdown file that includes relevant code context and project structure information.
4
+
5
+ ## What's included in snapshots?
6
+ - Selected code files and their contents
7
+ - Project structure (if enabled)
8
+ - Your prompt/question for the AI
9
+
10
+ ## Configuration
11
+ You can customize snapshot behavior in `config.json`.
@@ -0,0 +1,44 @@
1
+ # Thank you for using Snapshots for AI
2
+
3
+ Thanks for using Snapshots for AI. We hope this tool has helped you solve a problem or two.
4
+
5
+ If you would like to support our work, please help us by considering the following offers and requests:
6
+
7
+ ## Ways to Support
8
+
9
+ ### Join the GBTI Network!!! 🙏🙏🙏
10
+ The GBTI Network is a community of developers who are passionate about open source and community-driven development. Members enjoy access to exclussive tools, resources, a private MineCraft server, a listing in our members directory, co-op opportunities and more.
11
+
12
+ - Support our work by becoming a [GBTI Network member](https://gbti.network/membership/).
13
+
14
+ ### Try out BugHerd 🐛
15
+ BugHerd is a visual feedback and bug-tracking tool designed to streamline website development by enabling users to pin feedback directly onto web pages. This approach facilitates clear communication among clients, designers, developers, and project managers.
16
+
17
+ - Start your free trial with [BugHerd](https://partners.bugherd.com/55z6c8az8rvr) today.
18
+
19
+ ### Hire Developers from Codeable 👥
20
+ Codeable connects you with top-tier professionals skilled in frameworks and technologies such as Laravel, React, Django, Node, Vue.js, Angular, Ruby on Rails, and Node.js. Don't let the WordPress focus discourage you. Codeable experts do it all.
21
+
22
+ - Visit [Codeable](https://www.codeable.io/developers/?ref=z8h3e) to hire your next team member.
23
+
24
+ ### Lead positive reviews on our marketplace listing ⭐⭐⭐⭐⭐
25
+ - Rate us on [VSCode marketplace](https://marketplace.visualstudio.com/items?itemName=GBTI.snapshots-for-ai)
26
+ - Review us on [Cursor marketplace](https://open-vsx.org/extension/GBTI/snapshots-for-ai)
27
+
28
+ ### Star Our GitHub Repository ⭐
29
+ - Star and watch our [repository](https://github.com/gbti-network/vscode-snapshots-for-ai)
30
+
31
+ ### 📡 Stay Connected
32
+ Follow us on your favorite platforms for updates, news, and community discussions:
33
+ - **[Twitter/X](https://twitter.com/gbti_network)**
34
+ - **[GitHub](https://github.com/gbti-network)**
35
+ - **[YouTube](https://www.youtube.com/channel/UCh4FjB6r4oWQW-QFiwqv-UA)**
36
+ - **[Dev.to](https://dev.to/gbti)**
37
+ - **[Daily.dev](https://dly.to/zfCriM6JfRF)**
38
+ - **[Hashnode](https://gbti.hashnode.dev/)**
39
+ - **[Discord Community](https://gbti.network)**
40
+ - **[Reddit Community](https://www.reddit.com/r/GBTI_network)**
41
+
42
+ ---
43
+
44
+ Thank you for supporting open source software! 🙏
package/database/mysql.js CHANGED
@@ -20,6 +20,15 @@ class MySQLDatabase extends IDatabase{
20
20
  port: config.port || 3306,
21
21
  user: config.user,
22
22
  password: config.password,
23
+ typeCast: function (field, next) {
24
+ if (field.type === 'TINY' && field.length === 1) {
25
+ return (field.string() === '1'); // Convert tinyint(1) to boolean
26
+ }
27
+ if (field.type === 'INT' || field.type === 'DECIMAL' || field.type === 'NEWDECIMAL' || field.type === 'FLOAT' || field.type === 'DOUBLE') {
28
+ return Number(field.string()); // Convert numeric types to Number
29
+ }
30
+ return next();
31
+ }
23
32
  });
24
33
 
25
34
  await connection.query(`CREATE DATABASE IF NOT EXISTS \`${config.database}\``);
@@ -34,6 +43,15 @@ class MySQLDatabase extends IDatabase{
34
43
  waitForConnections: true,
35
44
  connectionLimit: config.connectionLimit || 10,
36
45
  queueLimit: 0,
46
+ typeCast: function (field, next) {
47
+ if (field.type === 'TINY' && field.length === 1) {
48
+ return (field.string() === '1'); // Convert tinyint(1) to boolean
49
+ }
50
+ if (field.type === 'INT' || field.type === 'DECIMAL' || field.type === 'NEWDECIMAL' || field.type === 'FLOAT' || field.type === 'DOUBLE') {
51
+ return Number(field.string()); // Convert numeric types to Number
52
+ }
53
+ return next();
54
+ }
37
55
  });
38
56
 
39
57
  this._connected = true;
@@ -46,6 +64,111 @@ class MySQLDatabase extends IDatabase{
46
64
  });
47
65
  }
48
66
 
67
+ /**
68
+ * Değerin türüne göre MySQL column türünü otomatik belirler
69
+ */
70
+ _getColumnType(value) {
71
+ if (value === null || value === undefined) {
72
+ return 'TEXT'; // Null değerler için varsayılan
73
+ }
74
+
75
+ if (typeof value === 'boolean') {
76
+ return 'BOOLEAN';
77
+ }
78
+
79
+ if (typeof value === 'number') {
80
+ if (Number.isInteger(value)) {
81
+ // Integer range kontrolü
82
+ if (value >= -128 && value <= 127) {
83
+ return 'TINYINT';
84
+ } else if (value >= -32768 && value <= 32767) {
85
+ return 'SMALLINT';
86
+ } else if (value >= -2147483648 && value <= 2147483647) {
87
+ return 'INT';
88
+ } else {
89
+ return 'BIGINT';
90
+ }
91
+ } else {
92
+ // Float/Double için
93
+ return 'DOUBLE';
94
+ }
95
+ }
96
+
97
+ if (typeof value === 'string') {
98
+ const length = value.length;
99
+ if (length <= 255) {
100
+ return 'VARCHAR(255)';
101
+ } else if (length <= 65535) {
102
+ return 'TEXT';
103
+ } else if (length <= 16777215) {
104
+ return 'MEDIUMTEXT';
105
+ } else {
106
+ return 'LONGTEXT';
107
+ }
108
+ }
109
+
110
+ if (typeof value === 'object') {
111
+ // Array ve Object'ler JSON olarak saklanır
112
+ const jsonString = JSON.stringify(value);
113
+ const length = jsonString.length;
114
+ if (length <= 65535) {
115
+ return 'JSON';
116
+ } else {
117
+ return 'LONGTEXT';
118
+ }
119
+ }
120
+
121
+ if (value instanceof Date) {
122
+ return 'DATETIME';
123
+ }
124
+
125
+ // Varsayılan
126
+ return 'TEXT';
127
+ }
128
+
129
+ /**
130
+ * Birden fazla değere göre en uygun column türünü belirler
131
+ */
132
+ _getBestColumnType(values) {
133
+ const types = values.map(val => this._getColumnType(val));
134
+ const uniqueTypes = [...new Set(types)];
135
+
136
+ // Eğer hepsi aynı türse, o türü kullan
137
+ if (uniqueTypes.length === 1) {
138
+ return uniqueTypes[0];
139
+ }
140
+
141
+ // Mixed türler için öncelik sırası
142
+ const typePriority = {
143
+ 'LONGTEXT': 10,
144
+ 'MEDIUMTEXT': 9,
145
+ 'TEXT': 8,
146
+ 'JSON': 7,
147
+ 'VARCHAR(255)': 6,
148
+ 'DATETIME': 5,
149
+ 'DOUBLE': 4,
150
+ 'BIGINT': 3,
151
+ 'INT': 2,
152
+ 'SMALLINT': 1,
153
+ 'TINYINT': 0,
154
+ 'BOOLEAN': -1
155
+ };
156
+
157
+ // En yüksek öncelikli türü seç
158
+ let bestType = uniqueTypes[0];
159
+ let bestPriority = typePriority[bestType] || 0;
160
+
161
+ for (const type of uniqueTypes) {
162
+ const priority = typePriority[type] || 0;
163
+ if (priority > bestPriority) {
164
+ bestType = type;
165
+ bestPriority = priority;
166
+ }
167
+ }
168
+
169
+ return bestType;
170
+ }
171
+
49
172
  async _queueRequest(operation) {
50
173
  if (this._connected) {
51
174
  return operation();
@@ -80,12 +203,25 @@ class MySQLDatabase extends IDatabase{
80
203
 
81
204
  async ensureTable(table, data = {}) {
82
205
  return this._queueRequest(async () => {
83
-
84
-
85
206
  const escapedTable = mysql.escape(table);
86
207
  const tables = await this.query(`SHOW TABLES LIKE ${escapedTable}`);
87
208
  if (tables.length === 0) {
88
- const columnDefinitions = Object.keys(data).map(col => `\`${col}\` VARCHAR(255)`); let columnsPart = ''; if (columnDefinitions.length > 0) { columnsPart = ', ' + columnDefinitions.join(", "); } const createTableSQL = ` CREATE TABLE \`${table}\` ( _id INT PRIMARY KEY AUTO_INCREMENT ${columnsPart} ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 `;
209
+ const columnDefinitions = Object.keys(data).map(col => {
210
+ const columnType = this._getColumnType(data[col]);
211
+ return `\`${col}\` ${columnType}`;
212
+ });
213
+
214
+ let columnsPart = '';
215
+ if (columnDefinitions.length > 0) {
216
+ columnsPart = ', ' + columnDefinitions.join(", ");
217
+ }
218
+
219
+ const createTableSQL = `
220
+ CREATE TABLE \`${table}\` (
221
+ _id INT PRIMARY KEY AUTO_INCREMENT
222
+ ${columnsPart}
223
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
224
+ `;
89
225
  await this.query(createTableSQL);
90
226
  }
91
227
  });
@@ -99,15 +235,24 @@ class MySQLDatabase extends IDatabase{
99
235
  if (!existingColumns) throw new Error(`Table ${table} does not exist.`);
100
236
 
101
237
  const existingNames = existingColumns.map(col => col.Field);
102
- for (const key of Object.keys(copy)) {
238
+ const primaryKeyColumn = existingColumns.find(col => col.Key === 'PRI' && col.Extra.includes('auto_increment'));
239
+
240
+ const insertData = { ...copy };
241
+ // Remove the auto-incrementing primary key from insertData if it's present
242
+ if (primaryKeyColumn && insertData[primaryKeyColumn.Field] !== undefined) {
243
+ delete insertData[primaryKeyColumn.Field];
244
+ }
245
+
246
+ for (const key of Object.keys(insertData)) {
103
247
  if (!existingNames.includes(key)) {
104
- await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` VARCHAR(255)`);
248
+ const columnType = this._getColumnType(insertData[key]);
249
+ await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` ${columnType}`);
105
250
  }
106
251
  }
107
252
 
108
- const keys = Object.keys(copy);
253
+ const keys = Object.keys(insertData);
109
254
  const placeholders = keys.map(() => "?").join(",");
110
- const values = Object.values(copy);
255
+ const values = Object.values(insertData).map(value => this._serializeValue(value));
111
256
  const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(",")}) VALUES (${placeholders})`;
112
257
 
113
258
  const result = await this.query(sql, values);
@@ -124,9 +269,10 @@ class MySQLDatabase extends IDatabase{
124
269
  const existingColumnNames = existingColumns.map(col => col.Field);
125
270
  for (const key of Object.keys(data)) {
126
271
  if (!existingColumnNames.includes(key)) {
127
- const alterSQL = `ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` VARCHAR(255)`;
272
+ const columnType = this._getColumnType(data[key]);
273
+ const alterSQL = `ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` ${columnType}`;
128
274
  await this.query(alterSQL);
129
- console.log(`Added missing column '${key}' to table '${table}'`);
275
+ console.log(`Added missing column '${key}' to table '${table}' with type ${columnType}`);
130
276
  }
131
277
  }
132
278
  const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(", ");
@@ -160,7 +306,13 @@ class MySQLDatabase extends IDatabase{
160
306
  params = Object.values(where);
161
307
  }
162
308
 
163
- return await this.query(sql, params);
309
+ return (await this.query(sql, params)).map(row => {
310
+ const newRow = {};
311
+ for (const key in row) {
312
+ newRow[key] = this._deserializeValue(row[key]);
313
+ }
314
+ return newRow;
315
+ });
164
316
  });
165
317
  }
166
318
 
@@ -173,9 +325,10 @@ class MySQLDatabase extends IDatabase{
173
325
  const existingColumnNames = existingColumns.map(col => col.Field);
174
326
  for (const key of Object.keys(data)) {
175
327
  if (!existingColumnNames.includes(key)) {
176
- const alterSQL = `ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` VARCHAR(255)`;
328
+ const columnType = this._getColumnType(data[key]);
329
+ const alterSQL = `ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` ${columnType}`;
177
330
  await this.query(alterSQL);
178
- console.log(`Added missing column '${key}' to table '${table}'`);
331
+ console.log(`Added missing column '${key}' to table '${table}' with type ${columnType}`);
179
332
  }
180
333
  }
181
334
  const existing = await this.select(table, where);
@@ -190,7 +343,14 @@ class MySQLDatabase extends IDatabase{
190
343
  async selectOne(table, where = null) {
191
344
  return this._queueRequest(async () => {
192
345
  const results = await this.select(table, where);
193
- return results[0] || null;
346
+ if (results[0]) {
347
+ const newResult = {};
348
+ for (const key in results[0]) {
349
+ newResult[key] = this._deserializeValue(results[0][key]);
350
+ }
351
+ return newResult;
352
+ }
353
+ return null;
194
354
  });
195
355
  }
196
356
 
@@ -214,9 +374,10 @@ class MySQLDatabase extends IDatabase{
214
374
  const existingColumnNames = existingColumns.map(col => col.Field);
215
375
  for (const key of Object.keys(data)) {
216
376
  if (!existingColumnNames.includes(key)) {
217
- const alterSQL = `ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` VARCHAR(255)`;
377
+ const columnType = this._getColumnType(data[key]);
378
+ const alterSQL = `ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` ${columnType}`;
218
379
  await this.query(alterSQL);
219
- console.log(`Added missing column '${key}' to table '${table}'`);
380
+ console.log(`Added missing column '${key}' to table '${table}' with type ${columnType}`);
220
381
  }
221
382
  }
222
383
  const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(", ");
@@ -236,15 +397,18 @@ class MySQLDatabase extends IDatabase{
236
397
  const existingColumnNames = existingColumns.map(col => col.Field);
237
398
  const keys = Object.keys(dataArray[0]);
238
399
 
239
- // Eksik kolonları sadece ilk elemana göre kontrol et
400
+ // Eksik kolonları kontrol et ve ekle
240
401
  for (const key of keys) {
241
402
  if (!existingColumnNames.includes(key)) {
242
- await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` VARCHAR(255)`);
403
+ // Tüm değerleri kontrol ederek en uygun türü belirle
404
+ const columnValues = dataArray.map(obj => obj[key]).filter(val => val !== undefined && val !== null);
405
+ const columnType = columnValues.length > 0 ? this._getBestColumnType(columnValues) : 'TEXT';
406
+ await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` ${columnType}`);
243
407
  }
244
408
  }
245
409
 
246
410
  const placeholders = dataArray.map(() => `(${keys.map(() => '?').join(',')})`).join(',');
247
- const values = dataArray.flatMap(obj => keys.map(k => obj[k]));
411
+ const values = dataArray.flatMap(obj => keys.map(k => this._serializeValue(obj[k])));
248
412
  const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(",")}) VALUES ${placeholders}`;
249
413
 
250
414
  const result = await this.query(sql, values);
@@ -255,6 +419,34 @@ class MySQLDatabase extends IDatabase{
255
419
  async close() {
256
420
  if (this.pool) await this.pool.end();
257
421
  }
422
+
423
+ // Helper to serialize values for storage
424
+ _serializeValue(value) {
425
+ if (value instanceof Date) {
426
+ return value.toISOString().slice(0, 19).replace('T', ' '); // MySQL DATETIME format
427
+ }
428
+ if (Array.isArray(value) || (typeof value === 'object' && value !== null)) {
429
+ return JSON.stringify(value);
430
+ }
431
+ return value;
432
+ }
433
+
434
+ // Helper to deserialize values after retrieval
435
+ _deserializeValue(value) {
436
+ try {
437
+ // Attempt to parse only if it looks like a JSON string (e.g., starts with [ or {)
438
+ if (typeof value === 'string' && (value.startsWith('[') || value.startsWith('{'))) {
439
+ const parsed = JSON.parse(value);
440
+ // Ensure it was actually an object or array, not just a string that happened to be valid JSON
441
+ if (typeof parsed === 'object' && parsed !== null) {
442
+ return parsed;
443
+ }
444
+ }
445
+ } catch (e) {
446
+ // Not a valid JSON string, return original value
447
+ }
448
+ return value;
449
+ }
258
450
  }
259
451
 
260
452
  module.exports = MySQLDatabase;
@@ -33,6 +33,93 @@ class SQLiteDatabase extends IDatabase{
33
33
  });
34
34
  }
35
35
 
36
+ /**
37
+ * Değerin türünü otomatik olarak tespit eder ve SQLite türünü döndürür.
38
+ * @param {any} value - Kontrol edilecek değer
39
+ * @returns {string} SQLite veri türü
40
+ */
41
+ _detectColumnType(value) {
42
+ if (value === null || value === undefined) {
43
+ return 'TEXT'; // Varsayılan olarak TEXT
44
+ }
45
+
46
+ // Boolean kontrolü
47
+ if (typeof value === 'boolean') {
48
+ return 'BOOLEAN';
49
+ }
50
+
51
+ // Number kontrolü
52
+ if (typeof value === 'number') {
53
+ // Tam sayı mı ondalık mı kontrol et
54
+ if (Number.isInteger(value)) {
55
+ return 'INTEGER';
56
+ } else {
57
+ return 'REAL';
58
+ }
59
+ }
60
+
61
+ // Date kontrolü
62
+ if (value instanceof Date) {
63
+ return 'DATETIME';
64
+ }
65
+
66
+ // String kontrolü - sayısal string'leri kontrol et
67
+ if (typeof value === 'string') {
68
+ // Boş string kontrolü
69
+ if (value.trim() === '') {
70
+ return 'TEXT';
71
+ }
72
+
73
+ // Tam sayı string kontrolü
74
+ if (/^-?\d+$/.test(value.trim())) {
75
+ return 'INTEGER';
76
+ }
77
+
78
+ // Ondalık sayı string kontrolü
79
+ if (/^-?\d+\.\d+$/.test(value.trim())) {
80
+ return 'REAL';
81
+ }
82
+
83
+ // Boolean string kontrolü
84
+ const lowerValue = value.toLowerCase().trim();
85
+ if (lowerValue === 'true' || lowerValue === 'false') {
86
+ return 'BOOLEAN';
87
+ }
88
+
89
+ // ISO date string kontrolü
90
+ if (value.match(/^\d{4}-\d{2}-\d{2}/) || value.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)) {
91
+ return 'DATETIME';
92
+ }
93
+ }
94
+
95
+ // Varsayılan olarak TEXT
96
+ return 'TEXT';
97
+ }
98
+
99
+ /**
100
+ * Birden fazla değerden en uygun sütun türünü belirler.
101
+ * @param {Array} values - Değer dizisi
102
+ * @returns {string} En uygun SQLite veri türü
103
+ */
104
+ _determineBestColumnType(values) {
105
+ const types = values.map(v => this._detectColumnType(v));
106
+
107
+ // Tür öncelik sırası: INTEGER < REAL < BOOLEAN < DATETIME < TEXT
108
+ const typePriority = {
109
+ 'INTEGER': 1,
110
+ 'REAL': 2,
111
+ 'BOOLEAN': 3,
112
+ 'DATETIME': 4,
113
+ 'TEXT': 5
114
+ };
115
+
116
+ // En yüksek öncelikli türü seç
117
+ const maxPriority = Math.max(...types.map(t => typePriority[t] || 5));
118
+ const bestType = Object.keys(typePriority).find(t => typePriority[t] === maxPriority);
119
+
120
+ return bestType || 'TEXT';
121
+ }
122
+
36
123
  /**
37
124
  * SQL sorgusu çalıştırır. Promise döndürür.
38
125
  * @param {string} sql - Çalıştırılacak SQL sorgusu.
@@ -62,13 +149,26 @@ class SQLiteDatabase extends IDatabase{
62
149
  * @param {object} data - Tablo oluşturulurken sütunları belirlemek için örnek veri.
63
150
  */
64
151
  async ensureTable(table, data = {}) {
65
-
66
-
67
152
  try {
68
153
  await this.query(`SELECT 1 FROM \`${table}\` LIMIT 1`);
69
154
  } catch (error) {
70
155
  if (error.message.includes('no such table')) {
71
- const columnDefinitions = Object.keys(data).map(col => `\`${col}\` TEXT`); let columnsPart = ''; if (columnDefinitions.length > 0) { columnsPart = ', ' + columnDefinitions.join(", "); } const createTableSQL = ` CREATE TABLE \`${table}\` ( _id INTEGER PRIMARY KEY AUTOINCREMENT ${columnsPart} ) `;
156
+ const columnDefinitions = Object.keys(data).map(col => {
157
+ const columnType = this._detectColumnType(data[col]);
158
+ return `\`${col}\` ${columnType}`;
159
+ });
160
+
161
+ let columnsPart = '';
162
+ if (columnDefinitions.length > 0) {
163
+ columnsPart = ', ' + columnDefinitions.join(", ");
164
+ }
165
+
166
+ const createTableSQL = `
167
+ CREATE TABLE \`${table}\` (
168
+ _id INTEGER PRIMARY KEY AUTOINCREMENT
169
+ ${columnsPart}
170
+ )
171
+ `;
72
172
  await this.query(createTableSQL);
73
173
  } else {
74
174
  throw error;
@@ -86,7 +186,8 @@ class SQLiteDatabase extends IDatabase{
86
186
 
87
187
  for (const key of Object.keys(data)) {
88
188
  if (!existingNames.includes(key)) {
89
- await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` TEXT`);
189
+ const columnType = this._detectColumnType(data[key]);
190
+ await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` ${columnType}`);
90
191
  }
91
192
  }
92
193
  }
@@ -211,8 +312,14 @@ class SQLiteDatabase extends IDatabase{
211
312
  */
212
313
  async bulkInsert(table, dataArray) {
213
314
  if (!Array.isArray(dataArray) || dataArray.length === 0) return 0;
315
+
316
+ // İlk elemanı tablo oluşturmak için kullan
214
317
  await this.ensureTable(table, dataArray[0]);
215
- await this._ensureColumns(table, dataArray[0]);
318
+
319
+ // Tüm elemanların sütunlarını kontrol et
320
+ for (const item of dataArray) {
321
+ await this._ensureColumns(table, item);
322
+ }
216
323
 
217
324
  const keys = Object.keys(dataArray[0]);
218
325
  const placeholders = keys.map(() => '?').join(',');
@@ -244,4 +351,4 @@ class SQLiteDatabase extends IDatabase{
244
351
  }
245
352
  }
246
353
 
247
- module.exports = SQLiteDatabase;
354
+ module.exports = SQLiteDatabase;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onurege3467/zerohelper",
3
- "version": "6.0.2",
3
+ "version": "6.2.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "node test.js"
package/test.js CHANGED
@@ -20,7 +20,7 @@ const mysqlConfig = {
20
20
  const mongoConfig = {
21
21
  adapter: 'mongodb',
22
22
  config: {
23
- url: process.env.MONGODB_URL || 'mongodb://localhost:27017/test',
23
+ url: process.env.MONGODB_URL || 'MONGODB_URL',
24
24
  database: process.env.MONGODB_DATABASE || 'test_mongo_db_zerohelper',
25
25
  cache: {
26
26
  max: 100,
@@ -56,6 +56,7 @@ const cachedSqliteConfig = {
56
56
  },
57
57
  };
58
58
 
59
+ // Absurd configurations for testing edge cases
59
60
  async function runDatabaseTests() {
60
61
  console.log('Starting database tests...');
61
62
 
@@ -75,7 +76,7 @@ async function runDatabaseTests() {
75
76
  console.log(`${name} database connected.`);
76
77
 
77
78
  // Test Insert
78
- const insertResult = await db.insert('users', { name: 'Test User', email: `test_${name.toLowerCase()}@example.com`, age: 30 });
79
+ const insertResult = await db.insert('users', { name: 'Test User', email: `test_${name.toLowerCase()}@example.com`, int_age: 30, bool_active: true });
79
80
  console.log(`${name} Insert:`, insertResult);
80
81
 
81
82
  // Test SelectOne
@@ -84,7 +85,7 @@ async function runDatabaseTests() {
84
85
 
85
86
  // Test Update
86
87
  if (user) {
87
- const updateResult = await db.update('users', { age: 31 }, { name: 'Test User' });
88
+ const updateResult = await db.update('users', { int_age: 31 }, { name: 'Test User' });
88
89
  console.log(`${name} Update:`, updateResult);
89
90
  }
90
91
 
@@ -158,6 +159,7 @@ async function runDatabaseTests() {
158
159
  }
159
160
  }
160
161
 
162
+
161
163
  console.log('\nAll database tests completed.');
162
164
  }
163
165
 
@@ -238,7 +240,6 @@ function runHelperFunctionTests() {
238
240
 
239
241
  async function main() {
240
242
  await runDatabaseTests();
241
- runHelperFunctionTests();
242
243
  }
243
244
 
244
245
  main();
package/data/test_db.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "users": []
3
- }
Binary file
Binary file