@onurege3467/zerohelper 10.1.0 → 10.2.5
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.
- package/dist/database/toon.js +11 -7
- package/dist/functions/toon.js +76 -51
- package/package.json +1 -1
package/dist/database/toon.js
CHANGED
|
@@ -42,13 +42,11 @@ class ToonDatabase extends IDatabase_1.IDatabase {
|
|
|
42
42
|
}
|
|
43
43
|
const content = await promises_1.default.readFile(this.filePath, 'utf-8');
|
|
44
44
|
const parsed = (0, toon_1.parse)(content);
|
|
45
|
-
// ✅ Parse sonucunu doğrula
|
|
46
45
|
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
47
46
|
this.db = {};
|
|
48
47
|
}
|
|
49
48
|
else {
|
|
50
49
|
this.db = {};
|
|
51
|
-
// Her tablonun array olduğundan emin ol
|
|
52
50
|
for (const [key, value] of Object.entries(parsed)) {
|
|
53
51
|
this.db[key] = Array.isArray(value) ? value : [];
|
|
54
52
|
}
|
|
@@ -60,7 +58,6 @@ class ToonDatabase extends IDatabase_1.IDatabase {
|
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
60
|
_getTable(table) {
|
|
63
|
-
// ✅ Her zaman array döndüren yardımcı fonksiyon
|
|
64
61
|
const data = this.db[table];
|
|
65
62
|
return Array.isArray(data) ? data : [];
|
|
66
63
|
}
|
|
@@ -121,7 +118,6 @@ class ToonDatabase extends IDatabase_1.IDatabase {
|
|
|
121
118
|
}
|
|
122
119
|
async ensureTable(table) {
|
|
123
120
|
await this.initPromise;
|
|
124
|
-
// ✅ Tablonun array olduğundan emin ol
|
|
125
121
|
if (!Array.isArray(this.db[table])) {
|
|
126
122
|
return this._queueRequest(() => {
|
|
127
123
|
this.db[table] = [];
|
|
@@ -178,7 +174,6 @@ class ToonDatabase extends IDatabase_1.IDatabase {
|
|
|
178
174
|
async select(table, where = null) {
|
|
179
175
|
return this._execute('select', table, async () => {
|
|
180
176
|
await this.initPromise;
|
|
181
|
-
// ✅ _getTable kullanarak array garantisi
|
|
182
177
|
const tableData = this._getTable(table);
|
|
183
178
|
const results = where && Object.keys(where).length > 0
|
|
184
179
|
? tableData.filter(row => Object.keys(where).every(k => String(row[k]) === String(where[k])))
|
|
@@ -191,9 +186,18 @@ class ToonDatabase extends IDatabase_1.IDatabase {
|
|
|
191
186
|
return res[0] || null;
|
|
192
187
|
}
|
|
193
188
|
async set(table, data, where) {
|
|
194
|
-
await this.
|
|
189
|
+
await this.initPromise;
|
|
190
|
+
await this.ensureTable(table);
|
|
195
191
|
const ex = await this.selectOne(table, where);
|
|
196
|
-
|
|
192
|
+
if (ex) {
|
|
193
|
+
// Kayıt varsa güncelle
|
|
194
|
+
await this.update(table, data, where);
|
|
195
|
+
return ex._id;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// Kayıt yoksa ekle
|
|
199
|
+
return this.insert(table, { ...where, ...data });
|
|
200
|
+
}
|
|
197
201
|
}
|
|
198
202
|
async bulkInsert(table, dataArray) {
|
|
199
203
|
return this._execute('bulkInsert', table, async () => {
|
package/dist/functions/toon.js
CHANGED
|
@@ -14,7 +14,7 @@ function stringify(data, indent = 0) {
|
|
|
14
14
|
if (typeof data === 'boolean' || typeof data === 'number')
|
|
15
15
|
return String(data);
|
|
16
16
|
if (typeof data === 'string') {
|
|
17
|
-
const hasSpecial =
|
|
17
|
+
const hasSpecial = /[,\n: ]/.test(data);
|
|
18
18
|
if (hasSpecial)
|
|
19
19
|
return '"' + data.replace(/"/g, '\\"') + '"';
|
|
20
20
|
return data;
|
|
@@ -23,27 +23,32 @@ function stringify(data, indent = 0) {
|
|
|
23
23
|
if (data.length === 0)
|
|
24
24
|
return '[]';
|
|
25
25
|
const first = data[0];
|
|
26
|
+
// ✅ FIX: Object array'leri için HER ZAMAN tabular format kullan (1+ eleman için)
|
|
26
27
|
if (typeof first === 'object' && first !== null && !Array.isArray(first)) {
|
|
27
28
|
const keys = Object.keys(first);
|
|
28
29
|
const isUniform = data.every(item => item && typeof item === 'object' &&
|
|
29
30
|
Object.keys(item).length === keys.length &&
|
|
30
31
|
Object.keys(item).every(k => keys.includes(k)));
|
|
31
|
-
if (isUniform
|
|
32
|
+
if (isUniform) {
|
|
32
33
|
const header = '[' + data.length + ']{' + keys.join(',') + '}:';
|
|
33
34
|
const rows = data.map(item => {
|
|
34
35
|
const rowValues = keys.map(k => {
|
|
35
36
|
const val = item[k];
|
|
36
37
|
if (val === null)
|
|
37
38
|
return 'null';
|
|
39
|
+
if (Array.isArray(val)) {
|
|
40
|
+
return '"' + JSON.stringify(val) + '"';
|
|
41
|
+
}
|
|
38
42
|
const valStr = String(val);
|
|
39
|
-
const hasSpecialRow =
|
|
40
|
-
return (typeof val === 'string' && hasSpecialRow) ? '"' + valStr + '"' : valStr;
|
|
43
|
+
const hasSpecialRow = /[,\n: ]/.test(valStr);
|
|
44
|
+
return (typeof val === 'string' && hasSpecialRow) ? '"' + valStr.replace(/"/g, '\\"') + '"' : valStr;
|
|
41
45
|
}).join(',');
|
|
42
46
|
return space + ' ' + rowValues;
|
|
43
47
|
});
|
|
44
48
|
return header + '\n' + rows.join('\n');
|
|
45
49
|
}
|
|
46
50
|
}
|
|
51
|
+
// Non-object array'ler için inline format
|
|
47
52
|
return '[' + data.length + ']: ' + data.map(v => stringify(v)).join(',');
|
|
48
53
|
}
|
|
49
54
|
if (typeof data === 'object') {
|
|
@@ -65,12 +70,22 @@ function stringify(data, indent = 0) {
|
|
|
65
70
|
function parse(toonStr) {
|
|
66
71
|
if (!toonStr || toonStr.trim() === '')
|
|
67
72
|
return {};
|
|
68
|
-
const lines = toonStr.split('\n')
|
|
73
|
+
const lines = toonStr.split('\n');
|
|
69
74
|
function parseValue(val) {
|
|
70
75
|
const trimmed = val.trim();
|
|
71
76
|
// Tırnak içindeki string
|
|
72
77
|
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
73
|
-
|
|
78
|
+
const unquoted = trimmed.slice(1, -1).replace(/\\"/g, '"');
|
|
79
|
+
// JSON array string'i kontrol et
|
|
80
|
+
try {
|
|
81
|
+
if (unquoted.startsWith('[') && unquoted.endsWith(']')) {
|
|
82
|
+
return JSON.parse(unquoted);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
// JSON değilse normal string döndür
|
|
87
|
+
}
|
|
88
|
+
return unquoted;
|
|
74
89
|
}
|
|
75
90
|
if (trimmed === 'true')
|
|
76
91
|
return true;
|
|
@@ -90,6 +105,30 @@ function parse(toonStr) {
|
|
|
90
105
|
const match = line.match(/^(\s*)/);
|
|
91
106
|
return match ? match[1].length : 0;
|
|
92
107
|
}
|
|
108
|
+
// CSV row parser with proper quote handling
|
|
109
|
+
function parseCSVRow(row) {
|
|
110
|
+
const result = [];
|
|
111
|
+
let current = '';
|
|
112
|
+
let inQuotes = false;
|
|
113
|
+
for (let i = 0; i < row.length; i++) {
|
|
114
|
+
const char = row[i];
|
|
115
|
+
if (char === '"' && (i === 0 || row[i - 1] !== '\\')) {
|
|
116
|
+
inQuotes = !inQuotes;
|
|
117
|
+
current += char;
|
|
118
|
+
}
|
|
119
|
+
else if (char === ',' && !inQuotes) {
|
|
120
|
+
result.push(current.trim());
|
|
121
|
+
current = '';
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
current += char;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (current.trim()) {
|
|
128
|
+
result.push(current.trim());
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
93
132
|
function processLines(startIndex, currentIndent) {
|
|
94
133
|
const result = {};
|
|
95
134
|
let i = startIndex;
|
|
@@ -97,49 +136,59 @@ function parse(toonStr) {
|
|
|
97
136
|
const line = lines[i];
|
|
98
137
|
const indent = getIndent(line);
|
|
99
138
|
const content = line.trim();
|
|
139
|
+
// Boş satırları atla
|
|
100
140
|
if (content === '') {
|
|
101
141
|
i++;
|
|
102
142
|
continue;
|
|
103
143
|
}
|
|
104
144
|
if (indent < currentIndent)
|
|
105
145
|
break;
|
|
106
|
-
//
|
|
107
|
-
const kvMatch = content.match(/^(
|
|
146
|
+
// Standard Key-Value match
|
|
147
|
+
const kvMatch = content.match(/^([^:]+):\s*(.*)$/);
|
|
108
148
|
if (kvMatch) {
|
|
109
|
-
const key = kvMatch[1];
|
|
149
|
+
const key = kvMatch[1].trim();
|
|
110
150
|
const valuePart = kvMatch[2].trim();
|
|
111
|
-
// ✅ FIX:
|
|
112
|
-
|
|
113
|
-
const tabularMatch = valuePart.match(/^\[(\d+)\]\{(.*)\}:$/);
|
|
151
|
+
// ✅ FIX: Tabular array header - Format: [count]{field1,field2,...}:
|
|
152
|
+
const tabularMatch = valuePart.match(/^\[(\d+)\]\{([^}]+)\}:$/);
|
|
114
153
|
if (tabularMatch) {
|
|
115
|
-
const
|
|
154
|
+
const expectedRowCount = parseInt(tabularMatch[1]);
|
|
116
155
|
const fields = tabularMatch[2].split(',').map(f => f.trim());
|
|
117
156
|
const rows = [];
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
157
|
+
let rowsRead = 0;
|
|
158
|
+
i++; // Header'dan sonraki satıra geç
|
|
159
|
+
while (i < lines.length && rowsRead < expectedRowCount) {
|
|
160
|
+
const rowLine = lines[i];
|
|
161
|
+
const rowIndent = getIndent(rowLine);
|
|
162
|
+
const rowContent = rowLine.trim();
|
|
163
|
+
// Boş satırları atla
|
|
164
|
+
if (rowContent === '') {
|
|
165
|
+
i++;
|
|
125
166
|
continue;
|
|
126
|
-
}
|
|
127
|
-
//
|
|
128
|
-
|
|
167
|
+
}
|
|
168
|
+
// Indent kontrolü - child satır olmalı
|
|
169
|
+
if (rowIndent <= currentIndent) {
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
// CSV parsing with quote support
|
|
173
|
+
const values = parseCSVRow(rowContent);
|
|
129
174
|
const row = {};
|
|
130
175
|
fields.forEach((f, idx) => {
|
|
131
176
|
row[f] = idx < values.length ? parseValue(values[idx]) : null;
|
|
132
177
|
});
|
|
133
178
|
rows.push(row);
|
|
179
|
+
rowsRead++;
|
|
180
|
+
i++;
|
|
134
181
|
}
|
|
135
182
|
result[key] = rows;
|
|
136
|
-
i++;
|
|
137
183
|
continue;
|
|
138
184
|
}
|
|
139
|
-
// ✅ Inline array
|
|
140
|
-
const inlineArrayMatch = valuePart.match(/^\[(\d+)\]:\s*(
|
|
185
|
+
// ✅ FIX: Inline array - [count]: value1,value2,...
|
|
186
|
+
const inlineArrayMatch = valuePart.match(/^\[(\d+)\]:\s*(.+)$/);
|
|
141
187
|
if (inlineArrayMatch) {
|
|
142
|
-
const
|
|
188
|
+
const count = parseInt(inlineArrayMatch[1]);
|
|
189
|
+
const valueStr = inlineArrayMatch[2].trim();
|
|
190
|
+
// Normal değer array'i (virgülle ayrılmış basit değerler)
|
|
191
|
+
const values = parseCSVRow(valueStr);
|
|
143
192
|
result[key] = values.map(v => parseValue(v));
|
|
144
193
|
i++;
|
|
145
194
|
continue;
|
|
@@ -160,30 +209,6 @@ function parse(toonStr) {
|
|
|
160
209
|
}
|
|
161
210
|
return [result, i];
|
|
162
211
|
}
|
|
163
|
-
// ✅ CSV row parser with quote support
|
|
164
|
-
function parseCSVRow(row) {
|
|
165
|
-
const result = [];
|
|
166
|
-
let current = '';
|
|
167
|
-
let inQuotes = false;
|
|
168
|
-
for (let i = 0; i < row.length; i++) {
|
|
169
|
-
const char = row[i];
|
|
170
|
-
if (char === '"' && (i === 0 || row[i - 1] !== '\\')) {
|
|
171
|
-
inQuotes = !inQuotes;
|
|
172
|
-
current += char;
|
|
173
|
-
}
|
|
174
|
-
else if (char === ',' && !inQuotes) {
|
|
175
|
-
result.push(current.trim());
|
|
176
|
-
current = '';
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
current += char;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (current) {
|
|
183
|
-
result.push(current.trim());
|
|
184
|
-
}
|
|
185
|
-
return result;
|
|
186
|
-
}
|
|
187
212
|
const [finalResult] = processLines(0, 0);
|
|
188
213
|
return finalResult;
|
|
189
214
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onurege3467/zerohelper",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.2.5",
|
|
4
4
|
"description": "ZeroHelper is a versatile high-performance utility library and database framework for Node.js, fully written in TypeScript.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|