jsql-neo 5.4.2 → 5.5.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 (72) hide show
  1. package/LICENSE +202 -202
  2. package/README.md +8097 -7971
  3. package/bin/jsql +320 -320
  4. package/bin/jsql-server +90 -90
  5. package/bin/jsql-server-control.js +177 -177
  6. package/index.d.ts +385 -357
  7. package/index.js +124 -118
  8. package/lib/ast.js +214 -0
  9. package/lib/btree.js +413 -413
  10. package/lib/cache.js +328 -328
  11. package/lib/client.js +125 -125
  12. package/lib/database.js +1744 -1744
  13. package/lib/date-types.js +182 -182
  14. package/lib/errors.js +89 -89
  15. package/lib/jsql_format.js +497 -497
  16. package/lib/migrate.js +254 -254
  17. package/lib/mod.js +292 -292
  18. package/lib/mongo_server.js +607 -607
  19. package/lib/multiserver.js +140 -140
  20. package/lib/mysql_compat.js +413 -413
  21. package/lib/mysql_server.js +1237 -1237
  22. package/lib/native_client.js +732 -732
  23. package/lib/nedb_compat.js +506 -506
  24. package/lib/pg_server.js +864 -864
  25. package/lib/plugin.js +34 -34
  26. package/lib/query.js +815 -815
  27. package/lib/redis_server.js +571 -571
  28. package/lib/sql.js +3460 -2925
  29. package/lib/sqlite_compat.js +323 -323
  30. package/lib/sqlite_worker.js +264 -264
  31. package/lib/table.js +1304 -1304
  32. package/lib/tui.js +502 -502
  33. package/lib/wasm.js +1 -1
  34. package/lib/wasm_client.js +718 -718
  35. package/lib/web_ui.js +257 -257
  36. package/native/jsql-neo-native.node +0 -0
  37. package/nativesrc/jsql-neo-core/Cargo.lock +455 -455
  38. package/nativesrc/jsql-neo-core/Cargo.toml +24 -24
  39. package/nativesrc/jsql-neo-core/src/engine/hybrid.rs +455 -455
  40. package/nativesrc/jsql-neo-core/src/engine/memory.rs +168 -168
  41. package/nativesrc/jsql-neo-core/src/engine/mod.rs +62 -62
  42. package/nativesrc/jsql-neo-core/src/engine/table.rs +700 -700
  43. package/nativesrc/jsql-neo-core/src/lib.rs +2 -2
  44. package/nativesrc/jsql-neo-core/src/storage/mod.rs +2 -2
  45. package/nativesrc/jsql-neo-core/src/storage/persistent.rs +1 -1
  46. package/nativesrc/jsql-neo-core/src/storage/wal.rs +85 -85
  47. package/nativesrc/jsql-neo-core/src/types.rs +93 -93
  48. package/nativesrc/jsql-neo-native/Cargo.lock +606 -606
  49. package/nativesrc/jsql-neo-native/Cargo.toml +16 -16
  50. package/nativesrc/jsql-neo-native/build.rs +3 -3
  51. package/nativesrc/jsql-neo-native/package.json +7 -7
  52. package/nativesrc/jsql-neo-native/src/lib.rs +269 -269
  53. package/nativesrc/jsql-neo-wasm/Cargo.lock +465 -465
  54. package/nativesrc/jsql-neo-wasm/Cargo.toml +15 -15
  55. package/nativesrc/jsql-neo-wasm/src/lib.rs +447 -447
  56. package/package.json +87 -86
  57. package/postinstall.js +158 -158
  58. package/test/btree.test.js +128 -128
  59. package/test/coverage.js +187 -187
  60. package/test/join.test.js +110 -110
  61. package/test/native.test.js +158 -158
  62. package/test/regress-5.1.0.js +271 -271
  63. package/test/smoke.js +58 -58
  64. package/test/sql-parser.test.js +273 -0
  65. package/test/wasm.test.js +110 -110
  66. package/wasm/browser.d.ts +89 -89
  67. package/wasm/browser.mjs +569 -569
  68. package/wasm/browser_bg.mjs +597 -597
  69. package/wasm/jsql_neo_wasm.d.ts +38 -38
  70. package/wasm/jsql_neo_wasm.js +520 -520
  71. package/wasm/jsql_neo_wasm_bg.wasm.d.ts +26 -26
  72. package/wasm/package.json +11 -11
package/lib/migrate.js CHANGED
@@ -1,254 +1,254 @@
1
- /*
2
- * Migration tools: mysqldump import, JSON import/export, CSV import/export.
3
- *
4
- * Works against any engine exposing:
5
- * hasTable(name) / getTableSchema(name) / find(name, {}, {limit, offset})
6
- * createTable(name, schema) / insert(name, rows) / executeSQL(sql, ...)
7
- * (Database instances and the jsql-neo MySQL server engine both qualify.)
8
- */
9
-
10
- const fs = require('fs');
11
- const path = require('path');
12
- const { splitStatements, executeSQL } = require('./sql');
13
- const { parseFieldShorthand } = require('./database');
14
-
15
- function normalizeSchema(schema) {
16
- const out = {};
17
- for (const [name, def] of Object.entries(schema || {})) {
18
- const d = typeof def === 'string' ? parseFieldShorthand(def.toLowerCase()) : { ...def };
19
- if (!d.type) d.type = typeof d === 'object' ? 'any' : 'string';
20
- if (d.type === 'int' || d.type === 'bigint' || d.type === 'smallint' || d.type === 'tinyint') d.type = 'integer';
21
- if (d.type === 'varchar' || d.type === 'text' || d.type === 'char') d.type = 'string';
22
- if (d.type === 'double' || d.type === 'real' || d.type === 'decimal' || d.type === 'numeric') d.type = 'float';
23
- if (d.type === 'bool') d.type = 'boolean';
24
- delete d.length;
25
- if (d.maxLength) { d.length = d.maxLength; delete d.maxLength; }
26
- out[name] = d;
27
- }
28
- return out;
29
- }
30
-
31
- function serializeValue(v) {
32
- if (v === null || v === undefined) return '';
33
- if (v instanceof Date) return v.toISOString();
34
- if (typeof v === 'object') return JSON.stringify(v);
35
- return String(v);
36
- }
37
-
38
- function parseValue(str, type) {
39
- if (str === '' || str === null || str === undefined) return null;
40
- const t = String(type || 'string').toLowerCase();
41
- if (t === 'integer') return Number.isFinite(Number(str)) ? Math.trunc(Number(str)) : str;
42
- if (t === 'float' || t === 'number') return Number.isFinite(Number(str)) ? Number(str) : str;
43
- if (t === 'boolean') {
44
- const s = str.toLowerCase();
45
- if (['1', 'true', 'yes', 'y'].includes(s)) return true;
46
- if (['0', 'false', 'no', 'n'].includes(s)) return false;
47
- return str;
48
- }
49
- if (t === 'object' || t === 'array') {
50
- try { return JSON.parse(str); } catch (e) { return str; }
51
- }
52
- return str;
53
- }
54
-
55
- function parseCSV(text) {
56
- const rows = [];
57
- let row = [];
58
- let field = '';
59
- let inQuotes = false;
60
- let i = 0;
61
- const n = text.length;
62
- while (i < n) {
63
- const c = text[i];
64
- if (inQuotes) {
65
- if (c === '"') {
66
- if (text[i + 1] === '"') { field += '"'; i += 2; continue; }
67
- inQuotes = false;
68
- i++;
69
- continue;
70
- }
71
- field += c;
72
- i++;
73
- continue;
74
- }
75
- if (c === '"' && field === '') { inQuotes = true; i++; continue; }
76
- if (c === ',') { row.push(field); field = ''; i++; continue; }
77
- if (c === '\n' || c === '\r') {
78
- if (c === '\r' && text[i + 1] === '\n') i++;
79
- row.push(field);
80
- field = '';
81
- if (row.length > 1 || row[0] !== '') rows.push(row);
82
- row = [];
83
- i++;
84
- continue;
85
- }
86
- field += c;
87
- i++;
88
- }
89
- if (field !== '' || row.length > 0) {
90
- row.push(field);
91
- if (row.length > 1 || row[0] !== '') rows.push(row);
92
- }
93
- return rows;
94
- }
95
-
96
- function toCSV(rows, columns) {
97
- const escape = (v) => {
98
- const s = serializeValue(v);
99
- return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
100
- };
101
- const lines = [columns.map(escape).join(',')];
102
- for (const r of rows) {
103
- lines.push(columns.map(c => escape(r[c])).join(','));
104
- }
105
- return lines.join('\n') + '\n';
106
- }
107
-
108
- /* ---------- JSON ---------- */
109
-
110
- async function exportTableToJSON(engine, table) {
111
- const schema = await engine.getTableSchema(table);
112
- if (!schema) throw new Error(`Table '${table}' does not exist`);
113
- const rows = await engine.find(table, {}, { limit: 1e9, offset: 0 });
114
- return { table, schema, rows };
115
- }
116
-
117
- async function exportAllToJSON(engine, tables) {
118
- const list = tables || await engine.getTables();
119
- const out = {};
120
- for (const t of list) out[t] = await exportTableToJSON(engine, t);
121
- return out;
122
- }
123
-
124
- async function importFromJSON(engine, data, opts = {}) {
125
- const overwrite = !!(opts && opts.overwrite);
126
- let tables = typeof data === 'string' ? JSON.parse(data) : data;
127
- // 兼容单表形状:exportTableToJSON 返回 { table, schema, rows }
128
- if (tables && !Array.isArray(tables) && typeof tables === 'object'
129
- && tables.table && tables.schema && !tables[tables.table]) {
130
- const single = tables;
131
- tables = {};
132
- tables[single.table] = single;
133
- }
134
- const created = [];
135
- let inserted = 0;
136
- for (const [name, t] of Object.entries(tables)) {
137
- if (!t || !t.schema) continue;
138
- if (engine.hasTable(name)) {
139
- if (!overwrite) throw new Error(`Table '${name}' already exists; pass { overwrite: true } to replace it`);
140
- await engine.dropTable(name);
141
- }
142
- await engine.createTable(name, normalizeSchema(t.schema));
143
- created.push(name);
144
- if (Array.isArray(t.rows) && t.rows.length > 0) {
145
- const ids = await engine.insert(name, t.rows.map(r => ({ ...r })));
146
- inserted += Array.isArray(ids) ? ids.length : t.rows.length;
147
- }
148
- }
149
- return { created, inserted };
150
- }
151
-
152
- /* ---------- CSV ---------- */
153
-
154
- async function exportTableToCSV(engine, table) {
155
- const schema = await engine.getTableSchema(table);
156
- if (!schema) throw new Error(`Table '${table}' does not exist`);
157
- const columns = Object.keys(schema);
158
- const rows = await engine.find(table, {}, { limit: 1e9, offset: 0 });
159
- return toCSV(rows, columns);
160
- }
161
-
162
- async function importFromCSV(engine, table, csv, opts = {}) {
163
- const schema = opts.schema || await engine.getTableSchema(table);
164
- const rows = parseCSV(csv);
165
- if (rows.length === 0) return { inserted: 0 };
166
- let columns;
167
- let start = 0;
168
- if (opts.header !== false) {
169
- columns = rows[0];
170
- start = 1;
171
- } else if (schema) {
172
- columns = Object.keys(schema);
173
- } else {
174
- columns = rows[0].map((_, i) => 'col' + (i + 1));
175
- }
176
- if (!engine.hasTable(table)) {
177
- if (!schema) {
178
- throw new Error(`Table '${table}' does not exist; provide opts.schema to create it`);
179
- }
180
- await engine.createTable(table, normalizeSchema(schema));
181
- }
182
- const dataRows = [];
183
- for (let i = start; i < rows.length; i++) {
184
- const row = {};
185
- for (let j = 0; j < columns.length; j++) {
186
- const type = schema && schema[columns[j]] ? schema[columns[j]].type : 'string';
187
- row[columns[j]] = parseValue(rows[i][j], type);
188
- }
189
- if (row.id === null || row.id === undefined || row.id === '') delete row.id;
190
- dataRows.push(row);
191
- }
192
- const ids = dataRows.length > 0 ? await engine.insert(table, dataRows) : [];
193
- return { inserted: dataRows.length, ids };
194
- }
195
-
196
- /* ---------- mysqldump ---------- */
197
-
198
- async function importDump(engine, sqlText, opts = {}) {
199
- const statements = splitStatements(sqlText);
200
- const created = [];
201
- let inserted = 0;
202
- const errors = [];
203
- for (const raw of statements) {
204
- const stmt = raw.trim();
205
- if (!stmt) continue;
206
- if (stmt.startsWith('--') || stmt.startsWith('#')) continue;
207
- const upper = stmt.toUpperCase();
208
- if (upper.startsWith('LOCK ') || upper.startsWith('UNLOCK ')) continue;
209
- if (upper.startsWith('/*!')) continue;
210
- if (upper.startsWith('SET ') && opts.skipSet !== false) continue;
211
- try {
212
- const r = await executeSQL(engine, stmt, { safety: false });
213
- if (r && r.type === 'createTable') created.push(r.table);
214
- if (r && r.type === 'insert') inserted += (r.ids || []).length || r.affectedRows || 0;
215
- } catch (e) {
216
- if (opts.strict) throw e;
217
- errors.push({ sql: stmt.slice(0, 120), error: e.message });
218
- }
219
- }
220
- return { created, inserted, errors };
221
- }
222
-
223
- async function importDumpFile(engine, filePath, opts = {}) {
224
- const text = fs.readFileSync(filePath, 'utf8');
225
- return importDump(engine, text, opts);
226
- }
227
-
228
- async function exportToFile(engine, table, filePath) {
229
- const ext = path.extname(filePath).toLowerCase();
230
- let content;
231
- if (ext === '.json') {
232
- content = JSON.stringify(await exportTableToJSON(engine, table), null, 2);
233
- } else if (ext === '.csv') {
234
- content = await exportTableToCSV(engine, table);
235
- } else {
236
- throw new Error('Unsupported export format (use .json or .csv): ' + filePath);
237
- }
238
- fs.writeFileSync(filePath, content);
239
- return content.length;
240
- }
241
-
242
- module.exports = {
243
- normalizeSchema,
244
- parseCSV,
245
- toCSV,
246
- exportTableToJSON,
247
- exportAllToJSON,
248
- importFromJSON,
249
- exportTableToCSV,
250
- importFromCSV,
251
- importDump,
252
- importDumpFile,
253
- exportToFile,
254
- };
1
+ /*
2
+ * Migration tools: mysqldump import, JSON import/export, CSV import/export.
3
+ *
4
+ * Works against any engine exposing:
5
+ * hasTable(name) / getTableSchema(name) / find(name, {}, {limit, offset})
6
+ * createTable(name, schema) / insert(name, rows) / executeSQL(sql, ...)
7
+ * (Database instances and the jsql-neo MySQL server engine both qualify.)
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const { splitStatements, executeSQL } = require('./sql');
13
+ const { parseFieldShorthand } = require('./database');
14
+
15
+ function normalizeSchema(schema) {
16
+ const out = {};
17
+ for (const [name, def] of Object.entries(schema || {})) {
18
+ const d = typeof def === 'string' ? parseFieldShorthand(def.toLowerCase()) : { ...def };
19
+ if (!d.type) d.type = typeof d === 'object' ? 'any' : 'string';
20
+ if (d.type === 'int' || d.type === 'bigint' || d.type === 'smallint' || d.type === 'tinyint') d.type = 'integer';
21
+ if (d.type === 'varchar' || d.type === 'text' || d.type === 'char') d.type = 'string';
22
+ if (d.type === 'double' || d.type === 'real' || d.type === 'decimal' || d.type === 'numeric') d.type = 'float';
23
+ if (d.type === 'bool') d.type = 'boolean';
24
+ delete d.length;
25
+ if (d.maxLength) { d.length = d.maxLength; delete d.maxLength; }
26
+ out[name] = d;
27
+ }
28
+ return out;
29
+ }
30
+
31
+ function serializeValue(v) {
32
+ if (v === null || v === undefined) return '';
33
+ if (v instanceof Date) return v.toISOString();
34
+ if (typeof v === 'object') return JSON.stringify(v);
35
+ return String(v);
36
+ }
37
+
38
+ function parseValue(str, type) {
39
+ if (str === '' || str === null || str === undefined) return null;
40
+ const t = String(type || 'string').toLowerCase();
41
+ if (t === 'integer') return Number.isFinite(Number(str)) ? Math.trunc(Number(str)) : str;
42
+ if (t === 'float' || t === 'number') return Number.isFinite(Number(str)) ? Number(str) : str;
43
+ if (t === 'boolean') {
44
+ const s = str.toLowerCase();
45
+ if (['1', 'true', 'yes', 'y'].includes(s)) return true;
46
+ if (['0', 'false', 'no', 'n'].includes(s)) return false;
47
+ return str;
48
+ }
49
+ if (t === 'object' || t === 'array') {
50
+ try { return JSON.parse(str); } catch (e) { return str; }
51
+ }
52
+ return str;
53
+ }
54
+
55
+ function parseCSV(text) {
56
+ const rows = [];
57
+ let row = [];
58
+ let field = '';
59
+ let inQuotes = false;
60
+ let i = 0;
61
+ const n = text.length;
62
+ while (i < n) {
63
+ const c = text[i];
64
+ if (inQuotes) {
65
+ if (c === '"') {
66
+ if (text[i + 1] === '"') { field += '"'; i += 2; continue; }
67
+ inQuotes = false;
68
+ i++;
69
+ continue;
70
+ }
71
+ field += c;
72
+ i++;
73
+ continue;
74
+ }
75
+ if (c === '"' && field === '') { inQuotes = true; i++; continue; }
76
+ if (c === ',') { row.push(field); field = ''; i++; continue; }
77
+ if (c === '\n' || c === '\r') {
78
+ if (c === '\r' && text[i + 1] === '\n') i++;
79
+ row.push(field);
80
+ field = '';
81
+ if (row.length > 1 || row[0] !== '') rows.push(row);
82
+ row = [];
83
+ i++;
84
+ continue;
85
+ }
86
+ field += c;
87
+ i++;
88
+ }
89
+ if (field !== '' || row.length > 0) {
90
+ row.push(field);
91
+ if (row.length > 1 || row[0] !== '') rows.push(row);
92
+ }
93
+ return rows;
94
+ }
95
+
96
+ function toCSV(rows, columns) {
97
+ const escape = (v) => {
98
+ const s = serializeValue(v);
99
+ return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
100
+ };
101
+ const lines = [columns.map(escape).join(',')];
102
+ for (const r of rows) {
103
+ lines.push(columns.map(c => escape(r[c])).join(','));
104
+ }
105
+ return lines.join('\n') + '\n';
106
+ }
107
+
108
+ /* ---------- JSON ---------- */
109
+
110
+ async function exportTableToJSON(engine, table) {
111
+ const schema = await engine.getTableSchema(table);
112
+ if (!schema) throw new Error(`Table '${table}' does not exist`);
113
+ const rows = await engine.find(table, {}, { limit: 1e9, offset: 0 });
114
+ return { table, schema, rows };
115
+ }
116
+
117
+ async function exportAllToJSON(engine, tables) {
118
+ const list = tables || await engine.getTables();
119
+ const out = {};
120
+ for (const t of list) out[t] = await exportTableToJSON(engine, t);
121
+ return out;
122
+ }
123
+
124
+ async function importFromJSON(engine, data, opts = {}) {
125
+ const overwrite = !!(opts && opts.overwrite);
126
+ let tables = typeof data === 'string' ? JSON.parse(data) : data;
127
+ // 兼容单表形状:exportTableToJSON 返回 { table, schema, rows }
128
+ if (tables && !Array.isArray(tables) && typeof tables === 'object'
129
+ && tables.table && tables.schema && !tables[tables.table]) {
130
+ const single = tables;
131
+ tables = {};
132
+ tables[single.table] = single;
133
+ }
134
+ const created = [];
135
+ let inserted = 0;
136
+ for (const [name, t] of Object.entries(tables)) {
137
+ if (!t || !t.schema) continue;
138
+ if (engine.hasTable(name)) {
139
+ if (!overwrite) throw new Error(`Table '${name}' already exists; pass { overwrite: true } to replace it`);
140
+ await engine.dropTable(name);
141
+ }
142
+ await engine.createTable(name, normalizeSchema(t.schema));
143
+ created.push(name);
144
+ if (Array.isArray(t.rows) && t.rows.length > 0) {
145
+ const ids = await engine.insert(name, t.rows.map(r => ({ ...r })));
146
+ inserted += Array.isArray(ids) ? ids.length : t.rows.length;
147
+ }
148
+ }
149
+ return { created, inserted };
150
+ }
151
+
152
+ /* ---------- CSV ---------- */
153
+
154
+ async function exportTableToCSV(engine, table) {
155
+ const schema = await engine.getTableSchema(table);
156
+ if (!schema) throw new Error(`Table '${table}' does not exist`);
157
+ const columns = Object.keys(schema);
158
+ const rows = await engine.find(table, {}, { limit: 1e9, offset: 0 });
159
+ return toCSV(rows, columns);
160
+ }
161
+
162
+ async function importFromCSV(engine, table, csv, opts = {}) {
163
+ const schema = opts.schema || await engine.getTableSchema(table);
164
+ const rows = parseCSV(csv);
165
+ if (rows.length === 0) return { inserted: 0 };
166
+ let columns;
167
+ let start = 0;
168
+ if (opts.header !== false) {
169
+ columns = rows[0];
170
+ start = 1;
171
+ } else if (schema) {
172
+ columns = Object.keys(schema);
173
+ } else {
174
+ columns = rows[0].map((_, i) => 'col' + (i + 1));
175
+ }
176
+ if (!engine.hasTable(table)) {
177
+ if (!schema) {
178
+ throw new Error(`Table '${table}' does not exist; provide opts.schema to create it`);
179
+ }
180
+ await engine.createTable(table, normalizeSchema(schema));
181
+ }
182
+ const dataRows = [];
183
+ for (let i = start; i < rows.length; i++) {
184
+ const row = {};
185
+ for (let j = 0; j < columns.length; j++) {
186
+ const type = schema && schema[columns[j]] ? schema[columns[j]].type : 'string';
187
+ row[columns[j]] = parseValue(rows[i][j], type);
188
+ }
189
+ if (row.id === null || row.id === undefined || row.id === '') delete row.id;
190
+ dataRows.push(row);
191
+ }
192
+ const ids = dataRows.length > 0 ? await engine.insert(table, dataRows) : [];
193
+ return { inserted: dataRows.length, ids };
194
+ }
195
+
196
+ /* ---------- mysqldump ---------- */
197
+
198
+ async function importDump(engine, sqlText, opts = {}) {
199
+ const statements = splitStatements(sqlText);
200
+ const created = [];
201
+ let inserted = 0;
202
+ const errors = [];
203
+ for (const raw of statements) {
204
+ const stmt = raw.trim();
205
+ if (!stmt) continue;
206
+ if (stmt.startsWith('--') || stmt.startsWith('#')) continue;
207
+ const upper = stmt.toUpperCase();
208
+ if (upper.startsWith('LOCK ') || upper.startsWith('UNLOCK ')) continue;
209
+ if (upper.startsWith('/*!')) continue;
210
+ if (upper.startsWith('SET ') && opts.skipSet !== false) continue;
211
+ try {
212
+ const r = await executeSQL(engine, stmt, { safety: false });
213
+ if (r && r.type === 'createTable') created.push(r.table);
214
+ if (r && r.type === 'insert') inserted += (r.ids || []).length || r.affectedRows || 0;
215
+ } catch (e) {
216
+ if (opts.strict) throw e;
217
+ errors.push({ sql: stmt.slice(0, 120), error: e.message });
218
+ }
219
+ }
220
+ return { created, inserted, errors };
221
+ }
222
+
223
+ async function importDumpFile(engine, filePath, opts = {}) {
224
+ const text = fs.readFileSync(filePath, 'utf8');
225
+ return importDump(engine, text, opts);
226
+ }
227
+
228
+ async function exportToFile(engine, table, filePath) {
229
+ const ext = path.extname(filePath).toLowerCase();
230
+ let content;
231
+ if (ext === '.json') {
232
+ content = JSON.stringify(await exportTableToJSON(engine, table), null, 2);
233
+ } else if (ext === '.csv') {
234
+ content = await exportTableToCSV(engine, table);
235
+ } else {
236
+ throw new Error('Unsupported export format (use .json or .csv): ' + filePath);
237
+ }
238
+ fs.writeFileSync(filePath, content);
239
+ return content.length;
240
+ }
241
+
242
+ module.exports = {
243
+ normalizeSchema,
244
+ parseCSV,
245
+ toCSV,
246
+ exportTableToJSON,
247
+ exportAllToJSON,
248
+ importFromJSON,
249
+ exportTableToCSV,
250
+ importFromCSV,
251
+ importDump,
252
+ importDumpFile,
253
+ exportToFile,
254
+ };