jtcsv 2.2.8 → 3.1.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 (246) hide show
  1. package/README.md +204 -115
  2. package/bin/jtcsv.ts +2612 -0
  3. package/browser.d.ts +142 -0
  4. package/dist/benchmark.js +446 -0
  5. package/dist/benchmark.js.map +1 -0
  6. package/dist/bin/jtcsv.js +1940 -0
  7. package/dist/bin/jtcsv.js.map +1 -0
  8. package/dist/csv-to-json.js +1262 -0
  9. package/dist/csv-to-json.js.map +1 -0
  10. package/dist/errors.js +291 -0
  11. package/dist/errors.js.map +1 -0
  12. package/dist/eslint.config.js +147 -0
  13. package/dist/eslint.config.js.map +1 -0
  14. package/dist/index-core.js +95 -0
  15. package/dist/index-core.js.map +1 -0
  16. package/dist/index.js +93 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/json-save.js +229 -0
  19. package/dist/json-save.js.map +1 -0
  20. package/dist/json-to-csv.js +576 -0
  21. package/dist/json-to-csv.js.map +1 -0
  22. package/dist/jtcsv-core.cjs.js +1736 -0
  23. package/dist/jtcsv-core.cjs.js.map +1 -0
  24. package/dist/jtcsv-core.esm.js +1708 -0
  25. package/dist/jtcsv-core.esm.js.map +1 -0
  26. package/dist/jtcsv-core.umd.js +1742 -0
  27. package/dist/jtcsv-core.umd.js.map +1 -0
  28. package/dist/jtcsv-full.cjs.js +2241 -0
  29. package/dist/jtcsv-full.cjs.js.map +1 -0
  30. package/dist/jtcsv-full.esm.js +2209 -0
  31. package/dist/jtcsv-full.esm.js.map +1 -0
  32. package/dist/jtcsv-full.umd.js +2247 -0
  33. package/dist/jtcsv-full.umd.js.map +1 -0
  34. package/dist/jtcsv-workers.esm.js +768 -0
  35. package/dist/jtcsv-workers.esm.js.map +1 -0
  36. package/dist/jtcsv-workers.umd.js +782 -0
  37. package/dist/jtcsv-workers.umd.js.map +1 -0
  38. package/dist/jtcsv.cjs.js +1996 -2048
  39. package/dist/jtcsv.cjs.js.map +1 -1
  40. package/dist/jtcsv.esm.js +1992 -2048
  41. package/dist/jtcsv.esm.js.map +1 -1
  42. package/dist/jtcsv.umd.js +2157 -2209
  43. package/dist/jtcsv.umd.js.map +1 -1
  44. package/dist/plugins/express-middleware/index.js +350 -0
  45. package/dist/plugins/express-middleware/index.js.map +1 -0
  46. package/dist/plugins/fastify-plugin/index.js +315 -0
  47. package/dist/plugins/fastify-plugin/index.js.map +1 -0
  48. package/dist/plugins/hono/index.js +111 -0
  49. package/dist/plugins/hono/index.js.map +1 -0
  50. package/dist/plugins/nestjs/index.js +112 -0
  51. package/dist/plugins/nestjs/index.js.map +1 -0
  52. package/dist/plugins/nuxt/index.js +53 -0
  53. package/dist/plugins/nuxt/index.js.map +1 -0
  54. package/dist/plugins/remix/index.js +133 -0
  55. package/dist/plugins/remix/index.js.map +1 -0
  56. package/dist/plugins/sveltekit/index.js +155 -0
  57. package/dist/plugins/sveltekit/index.js.map +1 -0
  58. package/dist/plugins/trpc/index.js +136 -0
  59. package/dist/plugins/trpc/index.js.map +1 -0
  60. package/dist/run-demo.js +49 -0
  61. package/dist/run-demo.js.map +1 -0
  62. package/dist/src/browser/browser-functions.js +193 -0
  63. package/dist/src/browser/browser-functions.js.map +1 -0
  64. package/dist/src/browser/core.js +123 -0
  65. package/dist/src/browser/core.js.map +1 -0
  66. package/dist/src/browser/csv-to-json-browser.js +353 -0
  67. package/dist/src/browser/csv-to-json-browser.js.map +1 -0
  68. package/dist/src/browser/errors-browser.js +219 -0
  69. package/dist/src/browser/errors-browser.js.map +1 -0
  70. package/dist/src/browser/extensions/plugins.js +106 -0
  71. package/dist/src/browser/extensions/plugins.js.map +1 -0
  72. package/dist/src/browser/extensions/workers.js +66 -0
  73. package/dist/src/browser/extensions/workers.js.map +1 -0
  74. package/dist/src/browser/index.js +140 -0
  75. package/dist/src/browser/index.js.map +1 -0
  76. package/dist/src/browser/json-to-csv-browser.js +225 -0
  77. package/dist/src/browser/json-to-csv-browser.js.map +1 -0
  78. package/dist/src/browser/streams.js +340 -0
  79. package/dist/src/browser/streams.js.map +1 -0
  80. package/dist/src/browser/workers/csv-parser.worker.js +264 -0
  81. package/dist/src/browser/workers/csv-parser.worker.js.map +1 -0
  82. package/dist/src/browser/workers/worker-pool.js +338 -0
  83. package/dist/src/browser/workers/worker-pool.js.map +1 -0
  84. package/dist/src/core/delimiter-cache.js +196 -0
  85. package/dist/src/core/delimiter-cache.js.map +1 -0
  86. package/dist/src/core/node-optimizations.js +279 -0
  87. package/dist/src/core/node-optimizations.js.map +1 -0
  88. package/dist/src/core/plugin-system.js +399 -0
  89. package/dist/src/core/plugin-system.js.map +1 -0
  90. package/dist/src/core/transform-hooks.js +348 -0
  91. package/dist/src/core/transform-hooks.js.map +1 -0
  92. package/dist/src/engines/fast-path-engine-new.js +262 -0
  93. package/dist/src/engines/fast-path-engine-new.js.map +1 -0
  94. package/dist/src/engines/fast-path-engine.js +671 -0
  95. package/dist/src/engines/fast-path-engine.js.map +1 -0
  96. package/dist/src/errors.js +18 -0
  97. package/dist/src/errors.js.map +1 -0
  98. package/dist/src/formats/ndjson-parser.js +332 -0
  99. package/dist/src/formats/ndjson-parser.js.map +1 -0
  100. package/dist/src/formats/tsv-parser.js +230 -0
  101. package/dist/src/formats/tsv-parser.js.map +1 -0
  102. package/dist/src/index-with-plugins.js +259 -0
  103. package/dist/src/index-with-plugins.js.map +1 -0
  104. package/dist/src/types/index.js +3 -0
  105. package/dist/src/types/index.js.map +1 -0
  106. package/dist/src/utils/bom-utils.js +267 -0
  107. package/dist/src/utils/bom-utils.js.map +1 -0
  108. package/dist/src/utils/encoding-support.js +77 -0
  109. package/dist/src/utils/encoding-support.js.map +1 -0
  110. package/dist/src/utils/schema-validator.js +609 -0
  111. package/dist/src/utils/schema-validator.js.map +1 -0
  112. package/dist/src/utils/transform-loader.js +281 -0
  113. package/dist/src/utils/transform-loader.js.map +1 -0
  114. package/dist/src/utils/validators.js +40 -0
  115. package/dist/src/utils/validators.js.map +1 -0
  116. package/dist/src/utils/zod-adapter.js +144 -0
  117. package/dist/src/utils/zod-adapter.js.map +1 -0
  118. package/dist/src/web-server/index.js +648 -0
  119. package/dist/src/web-server/index.js.map +1 -0
  120. package/dist/src/workers/csv-multithreaded.js +211 -0
  121. package/dist/src/workers/csv-multithreaded.js.map +1 -0
  122. package/dist/src/workers/csv-parser.worker.js +179 -0
  123. package/dist/src/workers/csv-parser.worker.js.map +1 -0
  124. package/dist/src/workers/worker-pool.js +228 -0
  125. package/dist/src/workers/worker-pool.js.map +1 -0
  126. package/dist/stream-csv-to-json.js +665 -0
  127. package/dist/stream-csv-to-json.js.map +1 -0
  128. package/dist/stream-json-to-csv.js +389 -0
  129. package/dist/stream-json-to-csv.js.map +1 -0
  130. package/examples/advanced/conditional-transformations.ts +446 -0
  131. package/examples/advanced/csv-parser.worker.ts +89 -0
  132. package/examples/advanced/nested-objects-example.ts +306 -0
  133. package/examples/advanced/performance-optimization.ts +504 -0
  134. package/examples/advanced/run-demo-server.ts +116 -0
  135. package/examples/advanced/web-worker-usage.html +874 -0
  136. package/examples/async-multithreaded-example.ts +335 -0
  137. package/examples/cli-advanced-usage.md +290 -0
  138. package/examples/{cli-batch-processing.js → cli-batch-processing.ts} +38 -38
  139. package/examples/{cli-tool.js → cli-tool.ts} +5 -8
  140. package/examples/{error-handling.js → error-handling.ts} +356 -324
  141. package/examples/{express-api.js → express-api.ts} +161 -164
  142. package/examples/{large-dataset-example.js → large-dataset-example.ts} +201 -182
  143. package/examples/{ndjson-processing.js → ndjson-processing.ts} +456 -434
  144. package/examples/{plugin-excel-exporter.js → plugin-excel-exporter.ts} +6 -7
  145. package/examples/react-integration.tsx +637 -0
  146. package/examples/{schema-validation.js → schema-validation.ts} +2 -2
  147. package/examples/simple-usage.ts +194 -0
  148. package/examples/{streaming-example.js → streaming-example.ts} +12 -12
  149. package/index.d.ts +187 -18
  150. package/package.json +75 -81
  151. package/plugins.d.ts +37 -0
  152. package/schema.d.ts +103 -0
  153. package/src/browser/browser-functions.ts +402 -0
  154. package/src/browser/core.ts +152 -0
  155. package/src/browser/csv-to-json-browser.d.ts +3 -0
  156. package/src/browser/csv-to-json-browser.ts +494 -0
  157. package/src/browser/{errors-browser.js → errors-browser.ts} +305 -197
  158. package/src/browser/extensions/plugins.ts +93 -0
  159. package/src/browser/extensions/workers.ts +39 -0
  160. package/src/browser/globals.d.ts +5 -0
  161. package/src/browser/index.ts +192 -0
  162. package/src/browser/json-to-csv-browser.d.ts +3 -0
  163. package/src/browser/json-to-csv-browser.ts +338 -0
  164. package/src/browser/streams.ts +403 -0
  165. package/src/browser/workers/{csv-parser.worker.js → csv-parser.worker.ts} +3 -3
  166. package/src/browser/workers/{worker-pool.js → worker-pool.ts} +51 -30
  167. package/src/core/delimiter-cache.ts +320 -0
  168. package/src/core/{node-optimizations.js → node-optimizations.ts} +448 -407
  169. package/src/core/plugin-system.ts +588 -0
  170. package/src/core/transform-hooks.ts +566 -0
  171. package/src/engines/{fast-path-engine-new.js → fast-path-engine-new.ts} +11 -2
  172. package/src/engines/{fast-path-engine.js → fast-path-engine.ts} +79 -53
  173. package/src/errors.ts +1 -0
  174. package/src/formats/{ndjson-parser.js → ndjson-parser.ts} +24 -16
  175. package/src/formats/{tsv-parser.js → tsv-parser.ts} +18 -17
  176. package/src/{index-with-plugins.js → index-with-plugins.ts} +381 -357
  177. package/src/types/index.ts +275 -0
  178. package/src/utils/bom-utils.ts +373 -0
  179. package/src/utils/encoding-support.ts +155 -0
  180. package/src/utils/{schema-validator.js → schema-validator.ts} +814 -589
  181. package/src/utils/transform-loader.ts +389 -0
  182. package/src/utils/validators.ts +35 -0
  183. package/src/utils/zod-adapter.ts +280 -0
  184. package/src/web-server/{index.js → index.ts} +19 -19
  185. package/src/workers/csv-multithreaded.ts +310 -0
  186. package/src/workers/csv-parser.worker.ts +227 -0
  187. package/src/workers/worker-pool.ts +409 -0
  188. package/bin/jtcsv.js +0 -2462
  189. package/csv-to-json.js +0 -688
  190. package/errors.js +0 -208
  191. package/examples/simple-usage.js +0 -282
  192. package/index.js +0 -68
  193. package/json-save.js +0 -254
  194. package/json-to-csv.js +0 -526
  195. package/plugins/README.md +0 -91
  196. package/plugins/express-middleware/README.md +0 -64
  197. package/plugins/express-middleware/example.js +0 -136
  198. package/plugins/express-middleware/index.d.ts +0 -114
  199. package/plugins/express-middleware/index.js +0 -360
  200. package/plugins/express-middleware/package.json +0 -52
  201. package/plugins/fastify-plugin/index.js +0 -406
  202. package/plugins/fastify-plugin/package.json +0 -55
  203. package/plugins/hono/README.md +0 -28
  204. package/plugins/hono/index.d.ts +0 -12
  205. package/plugins/hono/index.js +0 -36
  206. package/plugins/hono/package.json +0 -35
  207. package/plugins/nestjs/README.md +0 -35
  208. package/plugins/nestjs/index.d.ts +0 -25
  209. package/plugins/nestjs/index.js +0 -77
  210. package/plugins/nestjs/package.json +0 -37
  211. package/plugins/nextjs-api/README.md +0 -57
  212. package/plugins/nextjs-api/examples/ConverterComponent.jsx +0 -386
  213. package/plugins/nextjs-api/examples/api-convert.js +0 -69
  214. package/plugins/nextjs-api/index.js +0 -387
  215. package/plugins/nextjs-api/package.json +0 -63
  216. package/plugins/nextjs-api/route.js +0 -371
  217. package/plugins/nuxt/README.md +0 -24
  218. package/plugins/nuxt/index.js +0 -21
  219. package/plugins/nuxt/package.json +0 -35
  220. package/plugins/nuxt/runtime/composables/useJtcsv.js +0 -6
  221. package/plugins/nuxt/runtime/plugin.js +0 -6
  222. package/plugins/remix/README.md +0 -26
  223. package/plugins/remix/index.d.ts +0 -16
  224. package/plugins/remix/index.js +0 -62
  225. package/plugins/remix/package.json +0 -35
  226. package/plugins/sveltekit/README.md +0 -28
  227. package/plugins/sveltekit/index.d.ts +0 -17
  228. package/plugins/sveltekit/index.js +0 -54
  229. package/plugins/sveltekit/package.json +0 -33
  230. package/plugins/trpc/README.md +0 -25
  231. package/plugins/trpc/index.d.ts +0 -7
  232. package/plugins/trpc/index.js +0 -32
  233. package/plugins/trpc/package.json +0 -34
  234. package/src/browser/browser-functions.js +0 -219
  235. package/src/browser/csv-to-json-browser.js +0 -700
  236. package/src/browser/index.js +0 -113
  237. package/src/browser/json-to-csv-browser.js +0 -309
  238. package/src/browser/streams.js +0 -393
  239. package/src/core/delimiter-cache.js +0 -186
  240. package/src/core/plugin-system.js +0 -476
  241. package/src/core/transform-hooks.js +0 -350
  242. package/src/errors.js +0 -26
  243. package/src/utils/transform-loader.js +0 -205
  244. package/stream-csv-to-json.js +0 -542
  245. package/stream-json-to-csv.js +0 -464
  246. /package/examples/{web-workers-advanced.js → web-workers-advanced.ts} +0 -0
@@ -6,8 +6,18 @@
6
6
  * @date 2026-01-22
7
7
  */
8
8
 
9
- class FastPathEngine {
10
- constructor() {
9
+ class FastPathEngine {
10
+ compilers: Map<any, any>;
11
+ rowCompilers: Map<any, any>;
12
+ stats: {
13
+ simpleParserCount: number;
14
+ quoteAwareParserCount: number;
15
+ standardParserCount: number;
16
+ cacheHits: number;
17
+ cacheMisses: number;
18
+ };
19
+
20
+ constructor() {
11
21
  this.compilers = new Map();
12
22
  this.rowCompilers = new Map();
13
23
  this.stats = {
@@ -31,7 +41,7 @@ class FastPathEngine {
31
41
  return csv.indexOf('\\') !== -1;
32
42
  }
33
43
 
34
- _getStructureForParse(csv, options) {
44
+ _getStructureForParse(csv: any, options: any) {
35
45
  const sampleSize = Math.min(1000, csv.length);
36
46
  const sample = csv.substring(0, sampleSize);
37
47
  const structure = this.analyzeStructure(sample, options);
@@ -69,7 +79,7 @@ class FastPathEngine {
69
79
  /**
70
80
  * Анализирует структуру CSV и определяет оптимальный парсер
71
81
  */
72
- analyzeStructure(sample, options = {}) {
82
+ analyzeStructure(sample: any, options: any = {}) {
73
83
  const delimiter = options.delimiter || this._detectDelimiter(sample);
74
84
  const lines = sample.split('\n').slice(0, 10);
75
85
 
@@ -151,7 +161,7 @@ class FastPathEngine {
151
161
  /**
152
162
  * Выбирает оптимальный движок парсинга
153
163
  */
154
- _selectEngine(hasQuotes, hasNewlinesInFields, _fieldConsistency) {
164
+ _selectEngine(hasQuotes: any, hasNewlinesInFields: any, _fieldConsistency: any) {
155
165
  if (!hasQuotes && !hasNewlinesInFields) {
156
166
  return 'SIMPLE';
157
167
  }
@@ -181,7 +191,7 @@ class FastPathEngine {
181
191
  };
182
192
  }
183
193
 
184
- _emitSimpleRows(csv, delimiter, onRow) {
194
+ _emitSimpleRows(csv: any, delimiter: any, onRow: any) {
185
195
  let currentRow = [];
186
196
  let rowHasData = false;
187
197
  let fieldStart = 0;
@@ -190,9 +200,9 @@ class FastPathEngine {
190
200
  while (i <= csv.length) {
191
201
  const char = i < csv.length ? csv[i] : '\n';
192
202
 
193
- if (char !== '\r' && char !== '\n' && char !== ' ' && char !== '\t') {
194
- rowHasData = true;
195
- }
203
+ if (!rowHasData && char !== '\r' && char !== '\n' && char !== ' ' && char !== '\t') {
204
+ rowHasData = true;
205
+ }
196
206
 
197
207
  if (char === delimiter || char === '\n' || char === '\r' || i === csv.length) {
198
208
  const field = csv.slice(fieldStart, i);
@@ -217,7 +227,7 @@ class FastPathEngine {
217
227
  }
218
228
  }
219
229
 
220
- _emitSimpleRowsEscaped(csv, delimiter, onRow) {
230
+ _emitSimpleRowsEscaped(csv: any, delimiter: any, onRow: any) {
221
231
  let currentRow = [];
222
232
  let currentField = '';
223
233
  let rowHasData = false;
@@ -228,9 +238,9 @@ class FastPathEngine {
228
238
  const char = i < csv.length ? csv[i] : '\n';
229
239
  const nextChar = i + 1 < csv.length ? csv[i + 1] : '';
230
240
 
231
- if (char !== '\r' && char !== '\n' && char !== ' ' && char !== '\t') {
232
- rowHasData = true;
233
- }
241
+ if (!rowHasData && char !== '\r' && char !== '\n' && char !== ' ' && char !== '\t') {
242
+ rowHasData = true;
243
+ }
234
244
 
235
245
  if (escapeNext) {
236
246
  currentField += char;
@@ -288,7 +298,7 @@ class FastPathEngine {
288
298
  }
289
299
  }
290
300
 
291
- *_simpleRowsGenerator(csv, delimiter) {
301
+ *_simpleRowsGenerator(csv: any, delimiter: any) {
292
302
  let currentRow = [];
293
303
  let rowHasData = false;
294
304
  let fieldStart = 0;
@@ -324,7 +334,7 @@ class FastPathEngine {
324
334
  }
325
335
  }
326
336
 
327
- *_simpleEscapedRowsGenerator(csv, delimiter) {
337
+ *_simpleEscapedRowsGenerator(csv: any, delimiter: any) {
328
338
  let currentRow = [];
329
339
  let currentField = '';
330
340
  let rowHasData = false;
@@ -401,7 +411,7 @@ class FastPathEngine {
401
411
  _createSimpleRowEmitter(structure) {
402
412
  const { delimiter, hasBackslashes } = structure;
403
413
 
404
- return (csv, onRow) => {
414
+ return (csv: any, onRow: any) => {
405
415
  if (hasBackslashes) {
406
416
  this._emitSimpleRowsEscaped(csv, delimiter, onRow);
407
417
  } else {
@@ -437,7 +447,7 @@ class FastPathEngine {
437
447
  _createQuoteAwareRowEmitter(structure) {
438
448
  const { delimiter, hasEscapedQuotes, hasBackslashes } = structure;
439
449
 
440
- return (csv, onRow) => {
450
+ return (csv: any, onRow: any) => {
441
451
  const iterator = hasBackslashes
442
452
  ? this._quoteAwareEscapedRowsGenerator(csv, delimiter, hasEscapedQuotes)
443
453
  : this._quoteAwareRowsGenerator(csv, delimiter, hasEscapedQuotes);
@@ -448,7 +458,7 @@ class FastPathEngine {
448
458
  };
449
459
  }
450
460
 
451
- *_quoteAwareRowsGenerator(csv, delimiter, hasEscapedQuotes) {
461
+ *_quoteAwareRowsGenerator(csv: any, delimiter: any, hasEscapedQuotes: any) {
452
462
  let currentRow = [];
453
463
  let currentField = '';
454
464
  let rowHasData = false;
@@ -489,19 +499,27 @@ class FastPathEngine {
489
499
  continue;
490
500
  }
491
501
 
492
- let j = i + 1;
493
- while (j < csv.length && (csv[j] === ' ' || csv[j] === '\t')) {
494
- j++;
495
- }
496
- if (j >= csv.length || csv[j] === delimiter || csv[j] === '\n' || csv[j] === '\r') {
497
- insideQuotes = false;
498
- i++;
499
- continue;
500
- }
501
-
502
- currentField += '"';
503
- i++;
504
- continue;
502
+ if (nextChar === delimiter || nextChar === '\n' || nextChar === '\r' || i + 1 >= csv.length) {
503
+ insideQuotes = false;
504
+ i++;
505
+ continue;
506
+ }
507
+
508
+ if (nextChar === ' ' || nextChar === '\t') {
509
+ let j = i + 1;
510
+ while (j < csv.length && (csv[j] === ' ' || csv[j] === '\t')) {
511
+ j++;
512
+ }
513
+ if (j >= csv.length || csv[j] === delimiter || csv[j] === '\n' || csv[j] === '\r') {
514
+ insideQuotes = false;
515
+ i++;
516
+ continue;
517
+ }
518
+ }
519
+
520
+ currentField += '"';
521
+ i++;
522
+ continue;
505
523
  }
506
524
 
507
525
  insideQuotes = true;
@@ -537,8 +555,8 @@ class FastPathEngine {
537
555
 
538
556
  if (insideQuotes) {
539
557
  const error = new Error('Unclosed quotes in CSV');
540
- error.code = 'FAST_PATH_UNCLOSED_QUOTES';
541
- error.lineNumber = lineNumber;
558
+ (error as any).code = 'FAST_PATH_UNCLOSED_QUOTES';
559
+ (error as any).lineNumber = lineNumber;
542
560
  throw error;
543
561
  }
544
562
 
@@ -551,7 +569,7 @@ class FastPathEngine {
551
569
  }
552
570
  }
553
571
 
554
- *_quoteAwareEscapedRowsGenerator(csv, delimiter, hasEscapedQuotes) {
572
+ *_quoteAwareEscapedRowsGenerator(csv: any, delimiter: any, hasEscapedQuotes: any) {
555
573
  let currentRow = [];
556
574
  let currentField = '';
557
575
  let rowHasData = false;
@@ -624,19 +642,27 @@ class FastPathEngine {
624
642
  continue;
625
643
  }
626
644
 
627
- let j = i + 1;
628
- while (j < csv.length && (csv[j] === ' ' || csv[j] === '\t')) {
629
- j++;
630
- }
631
- if (j >= csv.length || csv[j] === delimiter || csv[j] === '\n' || csv[j] === '\r') {
632
- insideQuotes = false;
633
- i++;
634
- continue;
635
- }
636
-
637
- currentField += '"';
638
- i++;
639
- continue;
645
+ if (nextChar === delimiter || nextChar === '\n' || nextChar === '\r' || i + 1 >= csv.length) {
646
+ insideQuotes = false;
647
+ i++;
648
+ continue;
649
+ }
650
+
651
+ if (nextChar === ' ' || nextChar === '\t') {
652
+ let j = i + 1;
653
+ while (j < csv.length && (csv[j] === ' ' || csv[j] === '\t')) {
654
+ j++;
655
+ }
656
+ if (j >= csv.length || csv[j] === delimiter || csv[j] === '\n' || csv[j] === '\r') {
657
+ insideQuotes = false;
658
+ i++;
659
+ continue;
660
+ }
661
+ }
662
+
663
+ currentField += '"';
664
+ i++;
665
+ continue;
640
666
  }
641
667
 
642
668
  insideQuotes = true;
@@ -677,8 +703,8 @@ class FastPathEngine {
677
703
 
678
704
  if (insideQuotes) {
679
705
  const error = new Error('Unclosed quotes in CSV');
680
- error.code = 'FAST_PATH_UNCLOSED_QUOTES';
681
- error.lineNumber = lineNumber;
706
+ (error as any).code = 'FAST_PATH_UNCLOSED_QUOTES';
707
+ (error as any).lineNumber = lineNumber;
682
708
  throw error;
683
709
  }
684
710
 
@@ -759,7 +785,7 @@ class FastPathEngine {
759
785
  /**
760
786
  * Iterates rows without allocating the full result set.
761
787
  */
762
- *iterateRows(csv, options = {}) {
788
+ *iterateRows(csv: any, options = {}) {
763
789
  const structure = this._getStructureForParse(csv, options);
764
790
  const useEscapes = structure.hasBackslashes;
765
791
 
@@ -797,7 +823,7 @@ class FastPathEngine {
797
823
  /**
798
824
  * Парсит CSV с использованием оптимального парсера
799
825
  */
800
- parse(csv, options = {}) {
826
+ parse(csv: any, options = {}) {
801
827
  const structure = this._getStructureForParse(csv, options);
802
828
  const parser = this.compileParser(structure);
803
829
 
@@ -808,7 +834,7 @@ class FastPathEngine {
808
834
  * Parses CSV and emits rows via a callback to reduce memory usage.
809
835
  */
810
836
  /* istanbul ignore next */
811
- parseRows(csv, options = {}, onRow) {
837
+ parseRows(csv: any, options = {}, onRow: any) {
812
838
  for (const row of this.iterateRows(csv, options)) {
813
839
  onRow(row);
814
840
  }
@@ -841,4 +867,4 @@ class FastPathEngine {
841
867
  }
842
868
  }
843
869
 
844
- module.exports = FastPathEngine;
870
+ export default FastPathEngine;
package/src/errors.ts ADDED
@@ -0,0 +1 @@
1
+ export * from '../errors';
@@ -11,7 +11,7 @@ function createTextDecoder() {
11
11
  return new TextDecoder('utf-8');
12
12
  }
13
13
  try {
14
- const { TextDecoder: UtilTextDecoder } = require('util');
14
+ const { TextDecoder: UtilTextDecoder } = require("util");
15
15
  return new UtilTextDecoder('utf-8');
16
16
  } catch (_error) {
17
17
  return null;
@@ -23,7 +23,8 @@ function getTransformStream() {
23
23
  return TransformStream;
24
24
  }
25
25
  try {
26
- return require('stream/web').TransformStream;
26
+ const streamModule = require("stream/web");
27
+ return streamModule.TransformStream;
27
28
  } catch (_error) {
28
29
  return null;
29
30
  }
@@ -50,7 +51,7 @@ class NdjsonParser {
50
51
  * console.log(obj);
51
52
  * }
52
53
  */
53
- static async *parseStream(input, options = {}) {
54
+ static async *parseStream(input: any, options: any = {}) {
54
55
  const {
55
56
  bufferSize: _bufferSize = 64 * 1024, // 64KB буфер
56
57
  maxLineLength = 10 * 1024 * 1024, // 10MB максимальная длина строки
@@ -167,7 +168,7 @@ class NdjsonParser {
167
168
  * const ndjson = NdjsonParser.toNdjson(data);
168
169
  * // Результат: '{"name":"John"}\n{"name":"Jane"}'
169
170
  */
170
- static toNdjson(data, options = {}) {
171
+ static toNdjson(data: any, options: any = {}) {
171
172
  if (!Array.isArray(data)) {
172
173
  throw new Error('Input must be an array');
173
174
  }
@@ -193,7 +194,7 @@ class NdjsonParser {
193
194
  * const data = NdjsonParser.fromNdjson(ndjson);
194
195
  * // Результат: [{ name: 'John' }, { name: 'Jane' }]
195
196
  */
196
- static fromNdjson(ndjsonString, options = {}) {
197
+ static fromNdjson(ndjsonString: any, options: any = {}) {
197
198
  const {
198
199
  filter = null,
199
200
  transform = null,
@@ -202,7 +203,7 @@ class NdjsonParser {
202
203
 
203
204
  return ndjsonString
204
205
  .split('\n')
205
- .map((line, index) => {
206
+ .map((line: any, index: any) => {
206
207
  if (!line.trim()) {
207
208
  return null;
208
209
  }
@@ -232,7 +233,7 @@ class NdjsonParser {
232
233
  * @param {Object} options - Опции конвертации
233
234
  * @returns {TransformStream} Transform stream
234
235
  */
235
- static createNdjsonToCsvStream(options = {}) {
236
+ static createNdjsonToCsvStream(options: any = {}) {
236
237
  const {
237
238
  delimiter = ',',
238
239
  includeHeaders = true,
@@ -248,7 +249,7 @@ class NdjsonParser {
248
249
  }
249
250
 
250
251
  return new TransformStreamCtor({
251
- async transform(chunk, controller) {
252
+ async transform(chunk: any, controller: any) {
252
253
  try {
253
254
  const obj = JSON.parse(chunk);
254
255
 
@@ -270,7 +271,7 @@ class NdjsonParser {
270
271
  }
271
272
  },
272
273
 
273
- _escapeCsvField(value, delimiter) {
274
+ _escapeCsvField(value: any, delimiter: any) {
274
275
  if (value === null || value === undefined) {
275
276
  return '';
276
277
  }
@@ -292,7 +293,7 @@ class NdjsonParser {
292
293
  * @param {Object} options - Опции конвертации
293
294
  * @returns {TransformStream} Transform stream
294
295
  */
295
- static createCsvToNdjsonStream(options = {}) {
296
+ static createCsvToNdjsonStream(options: any = {}) {
296
297
  const {
297
298
  delimiter = ',',
298
299
  hasHeaders = true,
@@ -308,7 +309,7 @@ class NdjsonParser {
308
309
  }
309
310
 
310
311
  return new TransformStreamCtor({
311
- transform(chunk, controller) {
312
+ transform(chunk: any, controller: any) {
312
313
  const lines = chunk.toString().split('\n');
313
314
 
314
315
  for (const line of lines) {
@@ -323,11 +324,11 @@ class NdjsonParser {
323
324
  firstLine = false;
324
325
  } else {
325
326
  const obj = headers
326
- ? headers.reduce((acc, header, index) => {
327
+ ? headers.reduce((acc: any, header: any, index: any) => {
327
328
  acc[header] = fields[index] || '';
328
329
  return acc;
329
330
  }, {})
330
- : fields.reduce((acc, field, index) => {
331
+ : fields.reduce((acc: any, field: any, index: any) => {
331
332
  acc[`field_${index}`] = field;
332
333
  return acc;
333
334
  }, {});
@@ -337,7 +338,7 @@ class NdjsonParser {
337
338
  }
338
339
  },
339
340
 
340
- _parseCsvLine(line, delimiter) {
341
+ _parseCsvLine(line: any, delimiter: any) {
341
342
  const fields = [];
342
343
  let currentField = '';
343
344
  let insideQuotes = false;
@@ -378,7 +379,8 @@ class NdjsonParser {
378
379
  validLines: 0,
379
380
  errorLines: 0,
380
381
  totalBytes: 0,
381
- errors: []
382
+ errors: [],
383
+ successRate: 0
382
384
  };
383
385
 
384
386
  if (typeof input === 'string') {
@@ -464,4 +466,10 @@ class NdjsonParser {
464
466
  }
465
467
  }
466
468
 
467
- module.exports = NdjsonParser;
469
+ export default NdjsonParser;
470
+
471
+ // CommonJS compatibility
472
+ if (typeof module !== 'undefined' && module.exports) {
473
+ module.exports = NdjsonParser;
474
+ module.exports.default = NdjsonParser;
475
+ }
@@ -6,10 +6,13 @@
6
6
  * @date 2026-01-23
7
7
  */
8
8
 
9
- const { csvToJson } = require('../../csv-to-json');
10
- const { jsonToCsv } = require('../../json-to-csv');
11
- const { ValidationError, SecurityError, FileSystemError } = require('../../errors');
12
- const path = require('path');
9
+ import fs from "fs";
10
+ import path from "path";
11
+ import { csvToJson } from "../../csv-to-json";
12
+ import { jsonToCsv } from "../../json-to-csv";
13
+ import { ValidationError, SecurityError, FileSystemError } from "../../errors";
14
+ import { createJsonToCsvStream } from "../../stream-json-to-csv";
15
+ import { createCsvToJsonStream } from "../../stream-csv-to-json";
13
16
 
14
17
  function validateTsvFilePath(filePath) {
15
18
  if (typeof filePath !== 'string' || filePath.trim() === '') {
@@ -111,8 +114,6 @@ class TsvParser {
111
114
  * @returns {TransformStream} Transform stream
112
115
  */
113
116
  static createJsonToTsvStream(options = {}) {
114
- const { createJsonToCsvStream } = require('../../stream-json-to-csv');
115
-
116
117
  return createJsonToCsvStream({
117
118
  delimiter: '\t',
118
119
  ...options
@@ -125,8 +126,6 @@ class TsvParser {
125
126
  * @returns {TransformStream} Transform stream
126
127
  */
127
128
  static createTsvToJsonStream(options = {}) {
128
- const { createCsvToJsonStream } = require('../../stream-csv-to-json');
129
-
130
129
  return createCsvToJsonStream({
131
130
  delimiter: '\t',
132
131
  autoDetect: false,
@@ -141,11 +140,10 @@ class TsvParser {
141
140
  * @returns {Promise<Array>} Promise с массивом объектов
142
141
  */
143
142
  static async readTsvAsJson(filePath, options = {}) {
144
- const fs = require('fs').promises;
145
143
  const safePath = validateTsvFilePath(filePath);
146
144
 
147
145
  try {
148
- const tsvContent = await fs.readFile(safePath, 'utf8');
146
+ const tsvContent = await fs.promises.readFile(safePath, 'utf8');
149
147
  return csvToJson(tsvContent, {
150
148
  delimiter: '\t',
151
149
  autoDetect: false,
@@ -175,7 +173,6 @@ class TsvParser {
175
173
  * @returns {Array} Массив объектов
176
174
  */
177
175
  static readTsvAsJsonSync(filePath, options = {}) {
178
- const fs = require('fs');
179
176
  const safePath = validateTsvFilePath(filePath);
180
177
 
181
178
  try {
@@ -210,14 +207,13 @@ class TsvParser {
210
207
  * @returns {Promise<void>}
211
208
  */
212
209
  static async saveAsTsv(data, filePath, options = {}) {
213
- const fs = require('fs').promises;
214
210
  const safePath = validateTsvFilePath(filePath);
215
211
  const tsvContent = this.jsonToTsv(data, options);
216
212
  const dir = path.dirname(safePath);
217
213
 
218
214
  try {
219
- await fs.mkdir(dir, { recursive: true });
220
- await fs.writeFile(safePath, tsvContent, 'utf8');
215
+ await fs.promises.mkdir(dir, { recursive: true });
216
+ await fs.promises.writeFile(safePath, tsvContent, 'utf8');
221
217
  return safePath;
222
218
  } catch (error) {
223
219
  if (error.code === 'ENOENT') {
@@ -240,7 +236,6 @@ class TsvParser {
240
236
  * @param {Object} options - Опции сохранения
241
237
  */
242
238
  static saveAsTsvSync(data, filePath, options = {}) {
243
- const fs = require('fs');
244
239
  const safePath = validateTsvFilePath(filePath);
245
240
  const tsvContent = this.jsonToTsv(data, options);
246
241
 
@@ -254,7 +249,7 @@ class TsvParser {
254
249
  * @param {Object} options - Опции валидации
255
250
  * @returns {Object} Результат валидации
256
251
  */
257
- static validateTsv(tsvString, options = {}) {
252
+ static validateTsv(tsvString, options: any = {}) {
258
253
  const { requireConsistentColumns = true } = options;
259
254
 
260
255
  if (!tsvString || typeof tsvString !== 'string') {
@@ -336,4 +331,10 @@ class TsvParser {
336
331
  }
337
332
  }
338
333
 
339
- module.exports = TsvParser;
334
+ export default TsvParser;
335
+
336
+ // CommonJS compatibility
337
+ if (typeof module !== 'undefined' && module.exports) {
338
+ module.exports = TsvParser;
339
+ module.exports.default = TsvParser;
340
+ }