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
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const csv_to_json_1 = require("../../csv-to-json");
9
+ const json_to_csv_1 = require("../../json-to-csv");
10
+ const errors_1 = require("../../errors");
11
+ const stream_json_to_csv_1 = require("../../stream-json-to-csv");
12
+ const stream_csv_to_json_1 = require("../../stream-csv-to-json");
13
+ function validateTsvFilePath(filePath) {
14
+ if (typeof filePath !== 'string' || filePath.trim() === '') {
15
+ throw new errors_1.ValidationError('File path must be a non-empty string');
16
+ }
17
+ if (!filePath.toLowerCase().endsWith('.tsv')) {
18
+ throw new errors_1.ValidationError('File must have .tsv extension');
19
+ }
20
+ const normalizedPath = path_1.default.normalize(filePath);
21
+ if (normalizedPath.includes('..') ||
22
+ /\\\.\.\\|\/\.\.\//.test(filePath) ||
23
+ filePath.startsWith('..') ||
24
+ filePath.includes('/..')) {
25
+ throw new errors_1.SecurityError('Directory traversal detected in file path');
26
+ }
27
+ return path_1.default.resolve(filePath);
28
+ }
29
+ class TsvParser {
30
+ static jsonToTsv(data, options = {}) {
31
+ const defaultOptions = {
32
+ delimiter: '\t',
33
+ includeHeaders: true,
34
+ ...options
35
+ };
36
+ return (0, json_to_csv_1.jsonToCsv)(data, defaultOptions);
37
+ }
38
+ static tsvToJson(tsvString, options = {}) {
39
+ const defaultOptions = {
40
+ delimiter: '\t',
41
+ autoDetect: false,
42
+ hasHeaders: true,
43
+ ...options
44
+ };
45
+ return (0, csv_to_json_1.csvToJson)(tsvString, defaultOptions);
46
+ }
47
+ static isTsv(sample) {
48
+ if (!sample || typeof sample !== 'string') {
49
+ return false;
50
+ }
51
+ const lines = sample.split('\n').slice(0, 10);
52
+ let tabCount = 0;
53
+ let commaCount = 0;
54
+ let semicolonCount = 0;
55
+ for (const line of lines) {
56
+ if (line.trim() === '') {
57
+ continue;
58
+ }
59
+ tabCount += (line.match(/\t/g) || []).length;
60
+ commaCount += (line.match(/,/g) || []).length;
61
+ semicolonCount += (line.match(/;/g) || []).length;
62
+ }
63
+ return tabCount > commaCount && tabCount > semicolonCount;
64
+ }
65
+ static createJsonToTsvStream(options = {}) {
66
+ return (0, stream_json_to_csv_1.createJsonToCsvStream)({
67
+ delimiter: '\t',
68
+ ...options
69
+ });
70
+ }
71
+ static createTsvToJsonStream(options = {}) {
72
+ return (0, stream_csv_to_json_1.createCsvToJsonStream)({
73
+ delimiter: '\t',
74
+ autoDetect: false,
75
+ ...options
76
+ });
77
+ }
78
+ static async readTsvAsJson(filePath, options = {}) {
79
+ const safePath = validateTsvFilePath(filePath);
80
+ try {
81
+ const tsvContent = await fs_1.default.promises.readFile(safePath, 'utf8');
82
+ return (0, csv_to_json_1.csvToJson)(tsvContent, {
83
+ delimiter: '\t',
84
+ autoDetect: false,
85
+ ...options
86
+ });
87
+ }
88
+ catch (error) {
89
+ if (error instanceof errors_1.ValidationError || error instanceof errors_1.SecurityError) {
90
+ throw error;
91
+ }
92
+ if (error.code === 'ENOENT') {
93
+ throw new errors_1.FileSystemError(`File not found: ${safePath}`, error);
94
+ }
95
+ if (error.code === 'EACCES') {
96
+ throw new errors_1.FileSystemError(`Permission denied: ${safePath}`, error);
97
+ }
98
+ if (error.code === 'EISDIR') {
99
+ throw new errors_1.FileSystemError(`Path is a directory: ${safePath}`, error);
100
+ }
101
+ throw new errors_1.FileSystemError(`Failed to read TSV file: ${error.message}`, error);
102
+ }
103
+ }
104
+ static readTsvAsJsonSync(filePath, options = {}) {
105
+ const safePath = validateTsvFilePath(filePath);
106
+ try {
107
+ const tsvContent = fs_1.default.readFileSync(safePath, 'utf8');
108
+ return (0, csv_to_json_1.csvToJson)(tsvContent, {
109
+ delimiter: '\t',
110
+ autoDetect: false,
111
+ ...options
112
+ });
113
+ }
114
+ catch (error) {
115
+ if (error instanceof errors_1.ValidationError || error instanceof errors_1.SecurityError) {
116
+ throw error;
117
+ }
118
+ if (error.code === 'ENOENT') {
119
+ throw new errors_1.FileSystemError(`File not found: ${safePath}`, error);
120
+ }
121
+ if (error.code === 'EACCES') {
122
+ throw new errors_1.FileSystemError(`Permission denied: ${safePath}`, error);
123
+ }
124
+ if (error.code === 'EISDIR') {
125
+ throw new errors_1.FileSystemError(`Path is a directory: ${safePath}`, error);
126
+ }
127
+ throw new errors_1.FileSystemError(`Failed to read TSV file: ${error.message}`, error);
128
+ }
129
+ }
130
+ static async saveAsTsv(data, filePath, options = {}) {
131
+ const safePath = validateTsvFilePath(filePath);
132
+ const tsvContent = this.jsonToTsv(data, options);
133
+ const dir = path_1.default.dirname(safePath);
134
+ try {
135
+ await fs_1.default.promises.mkdir(dir, { recursive: true });
136
+ await fs_1.default.promises.writeFile(safePath, tsvContent, 'utf8');
137
+ return safePath;
138
+ }
139
+ catch (error) {
140
+ if (error.code === 'ENOENT') {
141
+ throw new errors_1.FileSystemError(`Directory does not exist: ${dir}`, error);
142
+ }
143
+ if (error.code === 'EACCES') {
144
+ throw new errors_1.FileSystemError(`Permission denied: ${safePath}`, error);
145
+ }
146
+ if (error.code === 'ENOSPC') {
147
+ throw new errors_1.FileSystemError(`No space left on device: ${safePath}`, error);
148
+ }
149
+ throw new errors_1.FileSystemError(`Failed to save TSV file: ${error.message}`, error);
150
+ }
151
+ }
152
+ static saveAsTsvSync(data, filePath, options = {}) {
153
+ const safePath = validateTsvFilePath(filePath);
154
+ const tsvContent = this.jsonToTsv(data, options);
155
+ fs_1.default.mkdirSync(path_1.default.dirname(safePath), { recursive: true });
156
+ fs_1.default.writeFileSync(safePath, tsvContent, 'utf8');
157
+ }
158
+ static validateTsv(tsvString, options = {}) {
159
+ const { requireConsistentColumns = true } = options;
160
+ if (!tsvString || typeof tsvString !== 'string') {
161
+ return {
162
+ valid: false,
163
+ error: 'Input must be a non-empty string',
164
+ details: { inputType: typeof tsvString }
165
+ };
166
+ }
167
+ const lines = tsvString.split('\n').filter(line => line.trim() !== '');
168
+ if (lines.length === 0) {
169
+ return {
170
+ valid: false,
171
+ error: 'No data found in TSV',
172
+ details: { lineCount: 0 }
173
+ };
174
+ }
175
+ const columnCounts = [];
176
+ const errors = [];
177
+ for (let i = 0; i < lines.length; i++) {
178
+ const line = lines[i];
179
+ const columns = line.split('\t');
180
+ columnCounts.push(columns.length);
181
+ if (options.disallowEmptyFields) {
182
+ const emptyFields = columns.filter(field => field.trim() === '');
183
+ if (emptyFields.length > 0) {
184
+ errors.push({
185
+ line: i + 1,
186
+ error: `Found ${emptyFields.length} empty field(s)`,
187
+ fields: emptyFields.map((_, idx) => idx + 1)
188
+ });
189
+ }
190
+ }
191
+ }
192
+ if (requireConsistentColumns && columnCounts.length > 1) {
193
+ const firstCount = columnCounts[0];
194
+ const inconsistentLines = [];
195
+ for (let i = 1; i < columnCounts.length; i++) {
196
+ if (columnCounts[i] !== firstCount) {
197
+ inconsistentLines.push({
198
+ line: i + 1,
199
+ expected: firstCount,
200
+ actual: columnCounts[i]
201
+ });
202
+ }
203
+ }
204
+ if (inconsistentLines.length > 0) {
205
+ errors.push({
206
+ error: 'Inconsistent column count',
207
+ details: inconsistentLines
208
+ });
209
+ }
210
+ }
211
+ const totalColumns = columnCounts[0] || 0;
212
+ return {
213
+ valid: errors.length === 0,
214
+ stats: {
215
+ totalLines: lines.length,
216
+ totalColumns,
217
+ minColumns: Math.min(...columnCounts),
218
+ maxColumns: Math.max(...columnCounts),
219
+ consistentColumns: new Set(columnCounts).size === 1
220
+ },
221
+ errors: errors.length > 0 ? errors : undefined
222
+ };
223
+ }
224
+ }
225
+ exports.default = TsvParser;
226
+ if (typeof module !== 'undefined' && module.exports) {
227
+ module.exports = TsvParser;
228
+ module.exports.default = TsvParser;
229
+ }
230
+ //# sourceMappingURL=tsv-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsv-parser.js","sourceRoot":"","sources":["../../../src/formats/tsv-parser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * TSV (Tab-Separated Values) парсер\n * Специализированная поддержка TSV формата\n * \n * @version 1.0.0\n * @date 2026-01-23\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { csvToJson } from \"../../csv-to-json\";\nimport { jsonToCsv } from \"../../json-to-csv\";\nimport { ValidationError, SecurityError, FileSystemError } from \"../../errors\";\nimport { createJsonToCsvStream } from \"../../stream-json-to-csv\";\nimport { createCsvToJsonStream } from \"../../stream-csv-to-json\";\n\nfunction validateTsvFilePath(filePath) {\n if (typeof filePath !== 'string' || filePath.trim() === '') {\n throw new ValidationError('File path must be a non-empty string');\n }\n\n if (!filePath.toLowerCase().endsWith('.tsv')) {\n throw new ValidationError('File must have .tsv extension');\n }\n\n const normalizedPath = path.normalize(filePath);\n if (normalizedPath.includes('..') ||\n /\\\\\\.\\.\\\\|\\/\\.\\.\\//.test(filePath) ||\n filePath.startsWith('..') ||\n filePath.includes('/..')) {\n throw new SecurityError('Directory traversal detected in file path');\n }\n\n return path.resolve(filePath);\n}\n\nclass TsvParser {\n /**\n * Конвертирует массив объектов в TSV строку\n * @param {Array} data - Массив объектов\n * @param {Object} options - Опции форматирования\n * @returns {string} TSV строка\n * \n * @example\n * const data = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }];\n * const tsv = TsvParser.jsonToTsv(data);\n * // Результат: \"id\\tname\\n1\\tJohn\\n2\\tJane\"\n */\n static jsonToTsv(data, options = {}) {\n const defaultOptions = {\n delimiter: '\\t',\n includeHeaders: true,\n ...options\n };\n \n return jsonToCsv(data, defaultOptions);\n }\n\n /**\n * Конвертирует TSV строку в массив объектов\n * @param {string} tsvString - TSV строка\n * @param {Object} options - Опции парсинга\n * @returns {Array} Массив объектов\n * \n * @example\n * const tsv = \"id\\tname\\n1\\tJohn\\n2\\tJane\";\n * const data = TsvParser.tsvToJson(tsv);\n * // Результат: [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]\n */\n static tsvToJson(tsvString, options = {}) {\n const defaultOptions = {\n delimiter: '\\t',\n autoDetect: false,\n hasHeaders: true,\n ...options\n };\n \n return csvToJson(tsvString, defaultOptions);\n }\n\n /**\n * Автоматически определяет является ли строка TSV\n * @param {string} sample - Образец данных\n * @returns {boolean} True если это TSV\n */\n static isTsv(sample) {\n if (!sample || typeof sample !== 'string') {\n return false;\n }\n\n const lines = sample.split('\\n').slice(0, 10);\n let tabCount = 0;\n let commaCount = 0;\n let semicolonCount = 0;\n\n for (const line of lines) {\n if (line.trim() === '') {\n continue;\n }\n \n // Считаем разделители\n tabCount += (line.match(/\\t/g) || []).length;\n commaCount += (line.match(/,/g) || []).length;\n semicolonCount += (line.match(/;/g) || []).length;\n }\n\n // Если табуляций больше чем других разделителей, считаем это TSV\n return tabCount > commaCount && tabCount > semicolonCount;\n }\n\n /**\n * Создает TransformStream для конвертации JSON в TSV\n * @param {Object} options - Опции конвертации\n * @returns {TransformStream} Transform stream\n */\n static createJsonToTsvStream(options = {}) {\n return createJsonToCsvStream({\n delimiter: '\\t',\n ...options\n });\n }\n\n /**\n * Создает TransformStream для конвертации TSV в JSON\n * @param {Object} options - Опции конвертации\n * @returns {TransformStream} Transform stream\n */\n static createTsvToJsonStream(options = {}) {\n return createCsvToJsonStream({\n delimiter: '\\t',\n autoDetect: false,\n ...options\n });\n }\n\n /**\n * Читает TSV файл и конвертирует в JSON\n * @param {string} filePath - Путь к TSV файлу\n * @param {Object} options - Опции парсинга\n * @returns {Promise<Array>} Promise с массивом объектов\n */\n static async readTsvAsJson(filePath, options = {}) {\n const safePath = validateTsvFilePath(filePath);\n\n try {\n const tsvContent = await fs.promises.readFile(safePath, 'utf8');\n return csvToJson(tsvContent, {\n delimiter: '\\t',\n autoDetect: false,\n ...options\n });\n } catch (error) {\n if (error instanceof ValidationError || error instanceof SecurityError) {\n throw error;\n }\n if (error.code === 'ENOENT') {\n throw new FileSystemError(`File not found: ${safePath}`, error);\n }\n if (error.code === 'EACCES') {\n throw new FileSystemError(`Permission denied: ${safePath}`, error);\n }\n if (error.code === 'EISDIR') {\n throw new FileSystemError(`Path is a directory: ${safePath}`, error);\n }\n throw new FileSystemError(`Failed to read TSV file: ${error.message}`, error);\n }\n }\n\n /**\n * Синхронно читает TSV файл и конвертирует в JSON\n * @param {string} filePath - Путь к TSV файлу\n * @param {Object} options - Опции парсинга\n * @returns {Array} Массив объектов\n */\n static readTsvAsJsonSync(filePath, options = {}) {\n const safePath = validateTsvFilePath(filePath);\n\n try {\n const tsvContent = fs.readFileSync(safePath, 'utf8');\n return csvToJson(tsvContent, {\n delimiter: '\\t',\n autoDetect: false,\n ...options\n });\n } catch (error) {\n if (error instanceof ValidationError || error instanceof SecurityError) {\n throw error;\n }\n if (error.code === 'ENOENT') {\n throw new FileSystemError(`File not found: ${safePath}`, error);\n }\n if (error.code === 'EACCES') {\n throw new FileSystemError(`Permission denied: ${safePath}`, error);\n }\n if (error.code === 'EISDIR') {\n throw new FileSystemError(`Path is a directory: ${safePath}`, error);\n }\n throw new FileSystemError(`Failed to read TSV file: ${error.message}`, error);\n }\n }\n\n /**\n * Сохраняет массив объектов как TSV файл\n * @param {Array} data - Массив объектов\n * @param {string} filePath - Путь для сохранения\n * @param {Object} options - Опции сохранения\n * @returns {Promise<void>}\n */\n static async saveAsTsv(data, filePath, options = {}) {\n const safePath = validateTsvFilePath(filePath);\n const tsvContent = this.jsonToTsv(data, options);\n const dir = path.dirname(safePath);\n\n try {\n await fs.promises.mkdir(dir, { recursive: true });\n await fs.promises.writeFile(safePath, tsvContent, 'utf8');\n return safePath;\n } catch (error) {\n if (error.code === 'ENOENT') {\n throw new FileSystemError(`Directory does not exist: ${dir}`, error);\n }\n if (error.code === 'EACCES') {\n throw new FileSystemError(`Permission denied: ${safePath}`, error);\n }\n if (error.code === 'ENOSPC') {\n throw new FileSystemError(`No space left on device: ${safePath}`, error);\n }\n throw new FileSystemError(`Failed to save TSV file: ${error.message}`, error);\n }\n }\n\n /**\n * Синхронно сохраняет массив объектов как TSV файл\n * @param {Array} data - Массив объектов\n * @param {string} filePath - Путь для сохранения\n * @param {Object} options - Опции сохранения\n */\n static saveAsTsvSync(data, filePath, options = {}) {\n const safePath = validateTsvFilePath(filePath);\n const tsvContent = this.jsonToTsv(data, options);\n\n fs.mkdirSync(path.dirname(safePath), { recursive: true });\n fs.writeFileSync(safePath, tsvContent, 'utf8');\n }\n\n /**\n * Валидирует TSV строку\n * @param {string} tsvString - TSV строка для валидации\n * @param {Object} options - Опции валидации\n * @returns {Object} Результат валидации\n */\n static validateTsv(tsvString, options: any = {}) {\n const { requireConsistentColumns = true } = options;\n \n if (!tsvString || typeof tsvString !== 'string') {\n return {\n valid: false,\n error: 'Input must be a non-empty string',\n details: { inputType: typeof tsvString }\n };\n }\n\n const lines = tsvString.split('\\n').filter(line => line.trim() !== '');\n \n if (lines.length === 0) {\n return {\n valid: false,\n error: 'No data found in TSV',\n details: { lineCount: 0 }\n };\n }\n\n const columnCounts = [];\n const errors = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const columns = line.split('\\t');\n columnCounts.push(columns.length);\n\n // Проверяем наличие пустых полей (если требуется)\n if (options.disallowEmptyFields) {\n const emptyFields = columns.filter(field => field.trim() === '');\n if (emptyFields.length > 0) {\n errors.push({\n line: i + 1,\n error: `Found ${emptyFields.length} empty field(s)`,\n fields: emptyFields.map((_, idx) => idx + 1)\n });\n }\n }\n }\n\n // Проверяем консистентность колонки\n if (requireConsistentColumns && columnCounts.length > 1) {\n const firstCount = columnCounts[0];\n const inconsistentLines = [];\n \n for (let i = 1; i < columnCounts.length; i++) {\n if (columnCounts[i] !== firstCount) {\n inconsistentLines.push({\n line: i + 1,\n expected: firstCount,\n actual: columnCounts[i]\n });\n }\n }\n\n if (inconsistentLines.length > 0) {\n errors.push({\n error: 'Inconsistent column count',\n details: inconsistentLines\n });\n }\n }\n\n /* istanbul ignore next */\n const totalColumns = columnCounts[0] || 0;\n\n return {\n valid: errors.length === 0,\n stats: {\n totalLines: lines.length,\n totalColumns,\n minColumns: Math.min(...columnCounts),\n maxColumns: Math.max(...columnCounts),\n consistentColumns: new Set(columnCounts).size === 1\n },\n errors: errors.length > 0 ? errors : undefined\n };\n }\n}\n\nexport default TsvParser;\n\n// CommonJS compatibility\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = TsvParser;\n module.exports.default = TsvParser;\n}\n"]}
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.create = exports.NdjsonParser = exports.FastPathEngine = exports.PluginManager = exports.JtcsvWithPlugins = void 0;
40
+ const plugin_system_1 = require("./core/plugin-system");
41
+ Object.defineProperty(exports, "PluginManager", { enumerable: true, get: function () { return plugin_system_1.PluginManager; } });
42
+ const fast_path_engine_1 = __importDefault(require("./engines/fast-path-engine"));
43
+ exports.FastPathEngine = fast_path_engine_1.default;
44
+ const ndjson_parser_1 = __importDefault(require("./formats/ndjson-parser"));
45
+ exports.NdjsonParser = ndjson_parser_1.default;
46
+ const json_to_csv_1 = require("../json-to-csv");
47
+ const csv_to_json_1 = require("../csv-to-json");
48
+ const json_to_csv_2 = require("../json-to-csv");
49
+ const csv_to_json_2 = require("../csv-to-json");
50
+ class JtcsvWithPlugins {
51
+ constructor(options = {}) {
52
+ this.pluginManager = new plugin_system_1.PluginManager();
53
+ this.fastPathEngine = new fast_path_engine_1.default();
54
+ this.options = {
55
+ enableFastPath: true,
56
+ enablePlugins: true,
57
+ ...options
58
+ };
59
+ this._registerBuiltinPlugins();
60
+ }
61
+ _registerBuiltinPlugins() {
62
+ this.pluginManager.use('fast-path-engine', {
63
+ name: 'Fast Path Engine',
64
+ version: '1.0.0',
65
+ description: 'Оптимизированный парсер CSV с автоматическим выбором стратегии',
66
+ hooks: {
67
+ 'before:csvToJson': (csv, context) => {
68
+ if (this.options.enableFastPath && context.options?.useFastPath !== false) {
69
+ const sample = csv.substring(0, Math.min(1000, csv.length));
70
+ const structure = this.fastPathEngine.analyzeStructure(sample, context.options);
71
+ context.metadata = context.metadata || {};
72
+ context.metadata.fastPathStructure = structure;
73
+ if (process.env.NODE_ENV === 'development') {
74
+ console.log(`🚀 Используется ${structure.recommendedEngine} парсер`);
75
+ }
76
+ }
77
+ return csv;
78
+ },
79
+ 'after:csvToJson': (result, context) => {
80
+ if (context.metadata?.fastPathStructure) {
81
+ context.metadata.fastPathStats = this.fastPathEngine.getStats();
82
+ }
83
+ return result;
84
+ }
85
+ }
86
+ });
87
+ this.pluginManager.use('ndjson-support', {
88
+ name: 'NDJSON Support',
89
+ version: '1.0.0',
90
+ description: 'Поддержка Newline Delimited JSON формата',
91
+ hooks: {
92
+ 'before:parse': (input, context) => {
93
+ if (context.options?.format === 'ndjson') {
94
+ return ndjson_parser_1.default.fromNdjson(input, context.options);
95
+ }
96
+ return input;
97
+ },
98
+ 'after:serialize': (output, context) => {
99
+ if (context.options?.format === 'ndjson') {
100
+ return ndjson_parser_1.default.toNdjson(output, context.options);
101
+ }
102
+ return output;
103
+ }
104
+ }
105
+ });
106
+ this.pluginManager.use('data-validation', {
107
+ name: 'Data Validation',
108
+ version: '1.0.0',
109
+ description: 'Валидация входных и выходных данных',
110
+ hooks: {
111
+ 'validation': (data, context) => {
112
+ if (!data) {
113
+ throw new Error('Данные не могут быть пустыми');
114
+ }
115
+ if (context.operation === 'jsonToCsv' && !Array.isArray(data)) {
116
+ throw new Error('Для конвертации в CSV данные должны быть массивом');
117
+ }
118
+ return data;
119
+ }
120
+ },
121
+ middlewares: [
122
+ async (ctx, next) => {
123
+ await this.pluginManager.executeHooks('validation', ctx.input, ctx);
124
+ await next();
125
+ await this.pluginManager.executeHooks('validation', ctx.result, ctx);
126
+ }
127
+ ]
128
+ });
129
+ this.pluginManager.use('logging', {
130
+ name: 'Logging',
131
+ version: '1.0.0',
132
+ description: 'Логирование операций',
133
+ hooks: {
134
+ 'before:csvToJson': (csv, context) => {
135
+ if (process.env.NODE_ENV === 'development') {
136
+ console.log(`📥 Начало csvToJson, размер: ${csv.length} байт`);
137
+ }
138
+ return csv;
139
+ },
140
+ 'after:csvToJson': (result, context) => {
141
+ if (process.env.NODE_ENV === 'development') {
142
+ console.log(`📤 Завершение csvToJson, результат: ${result.length} записей`);
143
+ }
144
+ return result;
145
+ },
146
+ 'before:jsonToCsv': (json, context) => {
147
+ if (process.env.NODE_ENV === 'development') {
148
+ console.log(`📥 Начало jsonToCsv, записей: ${json.length}`);
149
+ }
150
+ return json;
151
+ },
152
+ 'after:jsonToCsv': (csv, context) => {
153
+ if (process.env.NODE_ENV === 'development') {
154
+ console.log(`📤 Завершение jsonToCsv, размер: ${csv.length} байт`);
155
+ }
156
+ return csv;
157
+ }
158
+ }
159
+ });
160
+ }
161
+ async csvToJson(csv, options = {}) {
162
+ if (!this.options.enablePlugins) {
163
+ return (0, csv_to_json_1.csvToJson)(csv, options);
164
+ }
165
+ return this.pluginManager.executeWithPlugins('csvToJson', csv, options, (input, opts) => {
166
+ if (this.options.enableFastPath && opts?.useFastPath !== false) {
167
+ return (0, csv_to_json_1.csvToJson)(input, { ...opts, useFastPath: true });
168
+ }
169
+ return (0, csv_to_json_1.csvToJson)(input, opts);
170
+ });
171
+ }
172
+ async *csvToJsonIterator(csv, options = {}) {
173
+ if (!this.options.enablePlugins) {
174
+ for await (const row of (0, csv_to_json_1.csvToJsonIterator)(csv, options)) {
175
+ yield row;
176
+ }
177
+ return;
178
+ }
179
+ const iterator = await this.pluginManager.executeWithPlugins('csvToJson', csv, options, (input, opts) => {
180
+ if (this.options.enableFastPath && opts?.useFastPath !== false) {
181
+ return (0, csv_to_json_1.csvToJsonIterator)(input, { ...opts, useFastPath: true });
182
+ }
183
+ return (0, csv_to_json_1.csvToJsonIterator)(input, opts);
184
+ });
185
+ for await (const row of iterator) {
186
+ yield row;
187
+ }
188
+ }
189
+ async jsonToCsv(json, options = {}) {
190
+ if (!this.options.enablePlugins) {
191
+ return (0, json_to_csv_1.jsonToCsv)(json, options);
192
+ }
193
+ return this.pluginManager.executeWithPlugins('jsonToCsv', json, options, json_to_csv_1.jsonToCsv);
194
+ }
195
+ async saveAsCsv(data, filePath, options = {}) {
196
+ if (!this.options.enablePlugins) {
197
+ (0, json_to_csv_2.saveAsCsv)(data, filePath, options);
198
+ return;
199
+ }
200
+ const csv = await this.jsonToCsv(data, options);
201
+ await this.pluginManager.executeWithPlugins('saveAsCsv', { data: csv, filePath }, options, async (input) => {
202
+ const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
203
+ await fs.writeFile(input.filePath, input.data, 'utf8');
204
+ return input.filePath;
205
+ });
206
+ }
207
+ async readCsvAsJson(filePath, options = {}) {
208
+ if (!this.options.enablePlugins) {
209
+ return (0, csv_to_json_2.readCsvAsJson)(filePath, options);
210
+ }
211
+ const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
212
+ const csv = await fs.readFile(filePath, 'utf8');
213
+ return this.csvToJson(csv, options);
214
+ }
215
+ async parseNdjson(input, options = {}) {
216
+ if (typeof input === 'string') {
217
+ return ndjson_parser_1.default.fromNdjson(input, options);
218
+ }
219
+ const result = [];
220
+ for await (const obj of ndjson_parser_1.default.parseStream(input, options)) {
221
+ result.push(obj);
222
+ }
223
+ return result;
224
+ }
225
+ toNdjson(data, options = {}) {
226
+ return ndjson_parser_1.default.toNdjson(data, options);
227
+ }
228
+ use(name, plugin) {
229
+ this.pluginManager.use(name, plugin);
230
+ return this;
231
+ }
232
+ getPluginManager() {
233
+ return this.pluginManager;
234
+ }
235
+ getFastPathEngine() {
236
+ return this.fastPathEngine;
237
+ }
238
+ listPlugins() {
239
+ return this.pluginManager.listPlugins();
240
+ }
241
+ getStats() {
242
+ return {
243
+ plugins: this.pluginManager.getStats(),
244
+ fastPath: this.fastPathEngine.getStats(),
245
+ options: this.options
246
+ };
247
+ }
248
+ configure(newOptions) {
249
+ this.options = { ...this.options, ...newOptions };
250
+ return this;
251
+ }
252
+ static create(options = {}) {
253
+ return new JtcsvWithPlugins(options);
254
+ }
255
+ }
256
+ exports.JtcsvWithPlugins = JtcsvWithPlugins;
257
+ exports.default = JtcsvWithPlugins;
258
+ exports.create = JtcsvWithPlugins.create;
259
+ //# sourceMappingURL=index-with-plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-with-plugins.js","sourceRoot":"","sources":["../../src/index-with-plugins.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * JTCSV с поддержкой плагинов\r\n * Расширяемая версия основного API с plugin system\r\n * \r\n * @version 1.0.0\r\n * @date 2026-01-22\r\n */\r\n\r\nimport { PluginManager } from './core/plugin-system';\r\nimport FastPathEngine from './engines/fast-path-engine';\r\nimport NdjsonParser from './formats/ndjson-parser';\r\n\r\n// Импортируем основные функции\r\nimport { jsonToCsv as coreJsonToCsv } from '../json-to-csv';\r\nimport { csvToJson as coreCsvToJson, csvToJsonIterator as coreCsvToJsonIterator } from '../csv-to-json';\r\nimport { saveAsCsv as coreSaveAsCsv } from '../json-to-csv';\r\nimport { readCsvAsJson as coreReadCsvAsJson } from '../csv-to-json';\r\n\r\nimport type { CsvToJsonOptions, JsonToCsvOptions, SaveAsCsvOptions } from './types';\n\r\nexport interface JtcsvWithPluginsOptions {\r\n enableFastPath?: boolean;\r\n enablePlugins?: boolean;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface PluginHookContext {\r\n operation: string;\r\n options?: any;\r\n metadata?: Record<string, any>;\r\n}\r\n\r\nexport class JtcsvWithPlugins {\r\n private pluginManager: PluginManager;\r\n private fastPathEngine: FastPathEngine;\r\n private options: JtcsvWithPluginsOptions;\r\n\r\n constructor(options: JtcsvWithPluginsOptions = {}) {\r\n this.pluginManager = new PluginManager();\r\n this.fastPathEngine = new FastPathEngine();\r\n this.options = {\r\n enableFastPath: true,\r\n enablePlugins: true,\r\n ...options\r\n };\r\n\r\n // Регистрируем встроенные плагины\r\n this._registerBuiltinPlugins();\r\n }\r\n\r\n /**\r\n * Регистрирует встроенные плагины\r\n */\r\n private _registerBuiltinPlugins(): void {\r\n // Fast Path Engine плагин\r\n this.pluginManager.use('fast-path-engine', {\r\n name: 'Fast Path Engine',\r\n version: '1.0.0',\r\n description: 'Оптимизированный парсер CSV с автоматическим выбором стратегии',\r\n hooks: {\r\n 'before:csvToJson': (csv: string, context: PluginHookContext) => {\r\n if (this.options.enableFastPath && context.options?.useFastPath !== false) {\r\n // Используем fast path engine для анализа\r\n const sample = csv.substring(0, Math.min(1000, csv.length));\r\n const structure = this.fastPathEngine.analyzeStructure(sample, context.options);\r\n \r\n context.metadata = context.metadata || {};\r\n context.metadata.fastPathStructure = structure;\r\n if (process.env.NODE_ENV === 'development') {\r\n console.log(`🚀 Используется ${structure.recommendedEngine} парсер`);\r\n }\r\n }\r\n return csv;\r\n },\r\n 'after:csvToJson': (result: any[], context: PluginHookContext) => {\r\n if (context.metadata?.fastPathStructure) {\r\n context.metadata.fastPathStats = this.fastPathEngine.getStats();\r\n }\r\n return result;\r\n }\r\n }\r\n });\r\n\r\n // NDJSON плагин\r\n this.pluginManager.use('ndjson-support', {\r\n name: 'NDJSON Support',\r\n version: '1.0.0',\r\n description: 'Поддержка Newline Delimited JSON формата',\r\n hooks: {\r\n 'before:parse': (input: any, context: PluginHookContext) => {\r\n if (context.options?.format === 'ndjson') {\r\n // Парсим NDJSON\r\n return NdjsonParser.fromNdjson(input as string, context.options);\r\n }\r\n return input;\r\n },\r\n 'after:serialize': (output: any, context: PluginHookContext) => {\r\n if (context.options?.format === 'ndjson') {\r\n // Сериализуем в NDJSON\r\n return NdjsonParser.toNdjson(output, context.options);\r\n }\r\n return output;\r\n }\r\n }\r\n });\r\n\r\n // Валидация данных плагин\r\n this.pluginManager.use('data-validation', {\r\n name: 'Data Validation',\r\n version: '1.0.0',\r\n description: 'Валидация входных и выходных данных',\r\n hooks: {\r\n 'validation': (data: any, context: PluginHookContext) => {\r\n if (!data) {\r\n throw new Error('Данные не могут быть пустыми');\r\n }\r\n \r\n if (context.operation === 'jsonToCsv' && !Array.isArray(data)) {\r\n throw new Error('Для конвертации в CSV данные должны быть массивом');\r\n }\r\n \r\n return data;\r\n }\r\n },\r\n middlewares: [\r\n async (ctx: any, next: () => Promise<void>) => {\r\n // Валидация перед выполнением\r\n await this.pluginManager.executeHooks('validation', ctx.input, ctx);\r\n await next();\r\n // Валидация после выполнения\r\n await this.pluginManager.executeHooks('validation', ctx.result, ctx);\r\n }\r\n ]\r\n });\r\n\r\n // Логирование плагин\r\n this.pluginManager.use('logging', {\r\n name: 'Logging',\r\n version: '1.0.0',\r\n description: 'Логирование операций',\r\n hooks: {\r\n 'before:csvToJson': (csv: string, context: PluginHookContext) => {\r\n if (process.env.NODE_ENV === 'development') {\r\n console.log(`📥 Начало csvToJson, размер: ${csv.length} байт`);\r\n }\r\n return csv;\r\n },\r\n 'after:csvToJson': (result: any[], context: PluginHookContext) => {\r\n if (process.env.NODE_ENV === 'development') {\r\n console.log(`📤 Завершение csvToJson, результат: ${result.length} записей`);\r\n }\r\n return result;\r\n },\r\n 'before:jsonToCsv': (json: any[], context: PluginHookContext) => {\r\n if (process.env.NODE_ENV === 'development') {\r\n console.log(`📥 Начало jsonToCsv, записей: ${json.length}`);\r\n }\r\n return json;\r\n },\r\n 'after:jsonToCsv': (csv: string, context: PluginHookContext) => {\r\n if (process.env.NODE_ENV === 'development') {\r\n console.log(`📤 Завершение jsonToCsv, размер: ${csv.length} байт`);\r\n }\r\n return csv;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Конвертирует CSV в JSON с поддержкой плагинов\r\n * @param csv - CSV данные\r\n * @param options - Опции парсинга\r\n * @returns JSON данные\r\n */\r\n async csvToJson(csv: string, options: CsvToJsonOptions = {}): Promise<any[]> {\r\n if (!this.options.enablePlugins) {\r\n return coreCsvToJson(csv, options);\r\n }\r\n\r\n return this.pluginManager.executeWithPlugins(\r\n 'csvToJson',\r\n csv,\r\n options,\r\n (input: string, opts: CsvToJsonOptions) => {\r\n if (this.options.enableFastPath && opts?.useFastPath !== false) {\r\n return coreCsvToJson(input, { ...opts, useFastPath: true });\r\n }\r\n\r\n return coreCsvToJson(input, opts);\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Convert CSV to JSON rows as async iterator with plugin hooks.\r\n * @param csv - CSV input\r\n * @param options - Conversion options\r\n * @returns Async iterator of rows\r\n */\r\n async *csvToJsonIterator(csv: string, options: CsvToJsonOptions = {}): AsyncGenerator<any, void, unknown> {\r\n if (!this.options.enablePlugins) {\r\n for await (const row of coreCsvToJsonIterator(csv, options)) {\r\n yield row;\r\n }\r\n return;\r\n }\r\n\r\n const iterator = await this.pluginManager.executeWithPlugins(\r\n 'csvToJson',\r\n csv,\r\n options,\r\n (input: string, opts: CsvToJsonOptions) => {\r\n if (this.options.enableFastPath && opts?.useFastPath !== false) {\r\n return coreCsvToJsonIterator(input, { ...opts, useFastPath: true });\r\n }\r\n\r\n return coreCsvToJsonIterator(input, opts);\r\n }\r\n );\r\n\r\n for await (const row of iterator) {\r\n yield row;\r\n }\r\n }\r\n\r\n /**\r\n * Конвертирует JSON в CSV с поддержкой плагинов\r\n * @param json - JSON данные\r\n * @param options - Опции сериализации\r\n * @returns CSV данные\r\n */\r\n async jsonToCsv(json: any[], options: JsonToCsvOptions = {}): Promise<string> {\r\n if (!this.options.enablePlugins) {\r\n return coreJsonToCsv(json, options);\r\n }\r\n\r\n return this.pluginManager.executeWithPlugins(\r\n 'jsonToCsv',\r\n json,\r\n options,\r\n coreJsonToCsv\r\n );\r\n }\r\n\r\n /**\r\n * Сохраняет JSON как CSV файл\r\n * @param data - JSON данные\r\n * @param filePath - Путь к файлу\r\n * @param options - Опции\r\n * @returns Promise<void>\r\n */\r\n async saveAsCsv(data: any[], filePath: string, options: SaveAsCsvOptions = {}): Promise<void> {\n if (!this.options.enablePlugins) {\n coreSaveAsCsv(data, filePath, options);\n return;\n }\n\r\n const csv = await this.jsonToCsv(data, options);\r\n \r\n // Используем плагины для сохранения\r\n await this.pluginManager.executeWithPlugins(\n 'saveAsCsv',\n { data: csv, filePath },\n options,\n async (input: { data: string; filePath: string }) => {\n const fs = await import('fs/promises');\n await fs.writeFile(input.filePath, input.data, 'utf8');\n return input.filePath;\n }\n );\n }\n\r\n /**\r\n * Читает CSV файл и конвертирует в JSON\r\n * @param filePath - Путь к файлу\r\n * @param options - Опции\r\n * @returns JSON данные\r\n */\r\n async readCsvAsJson(filePath: string, options: CsvToJsonOptions = {}): Promise<any[]> {\r\n if (!this.options.enablePlugins) {\r\n return coreReadCsvAsJson(filePath, options);\r\n }\r\n\r\n // Читаем файл\r\n const fs = await import('fs/promises');\r\n const csv = await fs.readFile(filePath, 'utf8');\r\n \r\n // Конвертируем с использованием плагинов\r\n return this.csvToJson(csv, options);\r\n }\r\n\r\n /**\r\n * Парсит NDJSON данные\r\n * @param input - NDJSON данные\r\n * @param options - Опции\r\n * @returns JSON данные\r\n */\r\n async parseNdjson(input: string | ReadableStream, options: any = {}): Promise<any[]> {\r\n if (typeof input === 'string') {\r\n return NdjsonParser.fromNdjson(input, options);\r\n }\r\n \r\n // Для потоков\r\n const result: any[] = [];\r\n for await (const obj of NdjsonParser.parseStream(input, options)) {\r\n result.push(obj);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Конвертирует JSON в NDJSON\r\n * @param data - JSON данные\r\n * @param options - Опции\r\n * @returns NDJSON строка\r\n */\r\n toNdjson(data: any[], options: any = {}): string {\r\n return NdjsonParser.toNdjson(data, options);\r\n }\r\n\r\n /**\r\n * Регистрирует плагин\r\n * @param name - Имя плагина\r\n * @param plugin - Конфигурация плагина\r\n * @returns this для chaining\r\n */\r\n use(name: string, plugin: any): this {\r\n this.pluginManager.use(name, plugin);\r\n return this;\r\n }\r\n\r\n /**\r\n * Возвращает менеджер плагинов\r\n * @returns PluginManager\r\n */\r\n getPluginManager(): PluginManager {\r\n return this.pluginManager;\r\n }\r\n\r\n /**\r\n * Возвращает fast path engine\r\n * @returns FastPathEngine\r\n */\r\n getFastPathEngine(): FastPathEngine {\r\n return this.fastPathEngine;\r\n }\r\n\r\n /**\r\n * Возвращает список плагинов\r\n * @returns Array\r\n */\r\n listPlugins(): any[] {\r\n return this.pluginManager.listPlugins();\r\n }\r\n\r\n /**\r\n * Возвращает статистику\r\n * @returns Object\r\n */\r\n getStats(): any {\r\n return {\r\n plugins: this.pluginManager.getStats(),\r\n fastPath: this.fastPathEngine.getStats(),\r\n options: this.options\r\n };\r\n }\r\n\r\n /**\r\n * Настраивает опции\r\n * @param newOptions - Новые опции\r\n */\r\n configure(newOptions: JtcsvWithPluginsOptions): this {\r\n this.options = { ...this.options, ...newOptions };\r\n return this;\r\n }\r\n\r\n /**\r\n * Создает экземпляр с настройками по умолчанию\r\n * @param options - Опции\r\n * @returns JtcsvWithPlugins\r\n */\r\n static create(options: JtcsvWithPluginsOptions = {}): JtcsvWithPlugins {\r\n return new JtcsvWithPlugins(options);\r\n }\r\n}\r\n\r\n// Экспортируем основной класс\r\nexport default JtcsvWithPlugins;\r\n\r\n// Экспортируем утилиты\r\nexport { PluginManager, FastPathEngine, NdjsonParser };\r\n\r\n// Экспортируем фабричный метод\r\nexport const create = JtcsvWithPlugins.create;\n"]}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"","sourcesContent":["/**\r\n * TypeScript интерфейсы для проекта jtcsv\r\n */\r\n\r\n// Базовые типы\r\nexport type AnyObject = Record<string, any>;\r\nexport type AnyArray = any[];\r\n\r\n// JSON to CSV интерфейсы\r\nexport interface JsonToCsvOptions {\r\n /** CSV delimiter (default: ';') */\r\n delimiter?: string;\r\n /** Include headers row (default: true) */\r\n includeHeaders?: boolean;\r\n /** Rename column headers { oldKey: newKey } */\r\n renameMap?: Record<string, string>;\r\n /** Template for guaranteed column order */\r\n template?: Record<string, any>;\r\n /** Maximum number of records to process (optional, no limit by default) */\r\n maxRecords?: number;\r\n /** Prevent CSV injection attacks by escaping formulas (default: true) */\r\n preventCsvInjection?: boolean;\r\n /** Ensure RFC 4180 compliance (proper quoting, line endings) (default: true) */\r\n rfc4180Compliant?: boolean;\r\n /** Normalize excessive quotes in JSON string values before CSV export (default: true) */\r\n normalizeQuotes?: boolean;\r\n /** JSON schema for data validation and formatting */\r\n schema?: Record<string, any>;\r\n /** Whether to flatten nested objects into dot notation keys */\r\n flatten?: boolean;\r\n /** Separator for flattened keys (e.g., 'user.name' with '.') */\r\n flattenSeparator?: string;\r\n /** Maximum depth for flattening nested objects */\r\n flattenMaxDepth?: number;\r\n /** How to handle arrays ('stringify', 'join', 'expand') */\r\n arrayHandling?: 'stringify' | 'join' | 'expand';\r\n /** Warn when record count exceeds this threshold (default: 1000000) */\r\n memoryWarningThreshold?: number;\r\n /** Safety limit for in-memory conversion (default: 5000000). Set to Infinity to disable. */\r\n memoryLimit?: number;\r\n}\r\n\r\nexport interface SaveAsCsvOptions extends JsonToCsvOptions {\r\n /** Validate file path security (default: true) */\r\n validatePath?: boolean;\r\n}\r\n\r\n// CSV to JSON интерфейсы\r\nexport interface CsvToJsonOptions {\r\n /** CSV delimiter (default: auto-detected) */\r\n delimiter?: string;\r\n /** Auto-detect delimiter if not specified (default: true) */\r\n autoDetect?: boolean;\r\n /** Candidate delimiters for auto-detection (default: [';', ',', '\\t', '|']) */\r\n candidates?: string[];\r\n /** Whether CSV has headers row (default: true) */\r\n hasHeaders?: boolean;\r\n /** Map for renaming column headers { newKey: oldKey } */\r\n renameMap?: Record<string, string>;\r\n /** Trim whitespace from values (default: true) */\r\n trim?: boolean;\r\n /** Parse numeric values (default: false) */\r\n parseNumbers?: boolean;\r\n /** Parse boolean values (default: false) */\r\n parseBooleans?: boolean;\r\n /** Maximum number of rows to process (optional, no limit by default) */\r\n maxRows?: number;\r\n /** Enable fast-path parsing (default: true) */\r\n useFastPath?: boolean;\r\n /** Fast-path output mode (default: 'objects') */\r\n fastPathMode?: 'objects' | 'compact' | 'stream';\r\n /** JSON schema for validation and formatting */\r\n schema?: Record<string, any>;\r\n /** Custom transform function for each row */\r\n transform?: (row: Record<string, any>) => Record<string, any>;\r\n /** Use delimiter cache for auto-detection (default: true) */\r\n useCache?: boolean;\r\n /** Custom delimiter cache instance */\r\n cache?: any; // DelimiterCache type will be imported later\r\n /** Hooks for custom processing */\r\n hooks?: {\r\n beforeConvert?: (csv: string, options: CsvToJsonOptions) => string;\r\n perRow?: (row: Record<string, any>, index: number, context?: { options: CsvToJsonOptions }) => Record<string, any>;\r\n afterConvert?: (result: any[], options: CsvToJsonOptions) => any[];\r\n transformHooks?: import('../core/transform-hooks').TransformHooks;\r\n onError?: (error: Error, csv: string, options: CsvToJsonOptions) => void;\r\n };\r\n /** Prevent CSV injection attacks by escaping formulas (default: true) */\r\n preventCsvInjection?: boolean;\r\n /** Ensure RFC 4180 compliance (proper quoting, line endings) (default: true) */\r\n rfc4180Compliant?: boolean;\r\n /** Warn about extra fields not in headers (default: false) */\r\n warnExtraFields?: boolean;\r\n /** Error recovery strategy for row-level errors (default: 'throw') */\r\n onError?: 'skip' | 'warn' | 'throw';\r\n /** Custom error handler for row-level errors */\r\n errorHandler?: (error: Error, line: string, lineNumber: number) => void;\r\n /** Warn when row count exceeds this threshold (default: 1000000) */\r\n memoryWarningThreshold?: number;\r\n /** Safety limit for in-memory conversion (default: 5000000). Set to Infinity to disable. */\r\n memoryLimit?: number;\r\n /** Attempt to repair shifted rows with trailing empty fields (default: true) */\r\n repairRowShifts?: boolean;\r\n /** Normalize excessive quotes in parsed fields (default: true) */\r\n normalizeQuotes?: boolean;\r\n}\r\n\r\n// JSON save интерфейсы\r\nexport interface SaveAsJsonOptions {\r\n /** Format JSON with indentation (default: false) */\r\n prettyPrint?: boolean;\r\n /** Maximum file size in bytes (default: 10MB = 10485760) */\r\n maxSize?: number;\r\n}\r\n\r\n// Streaming интерфейсы\r\nexport interface JsonToCsvStreamOptions extends JsonToCsvOptions {\r\n /** Custom transform function for each row */\r\n transform?: (row: Record<string, any>) => Record<string, any>;\r\n /** JSON schema for validation and formatting */\r\n schema?: Record<string, any>;\r\n /** Add UTF-8 BOM for Excel compatibility (default: true) */\r\n addBOM?: boolean;\r\n}\r\n\r\nexport interface CsvToJsonStreamOptions extends CsvToJsonOptions {\r\n /** Custom transform function for each row */\r\n transform?: (row: Record<string, any>) => Record<string, any>;\r\n /** JSON schema for validation and formatting */\r\n schema?: Record<string, any>;\r\n}\r\n\r\n// NDJSON интерфейсы\r\nexport interface NdjsonOptions {\r\n /** Buffer size for streaming (default: 64KB) */\r\n bufferSize?: number;\r\n /** Maximum line length (default: 10MB) */\r\n maxLineLength?: number;\r\n /** Error handler callback */\r\n onError?: (error: Error, line: string, lineNumber: number) => void;\r\n /** JSON stringify replacer function */\r\n replacer?: (key: string, value: any) => any;\r\n /** JSON stringify space (indentation) */\r\n space?: number | string;\r\n /** Filter function for rows */\r\n filter?: (obj: Record<string, any>, index: number) => boolean;\r\n /** Transform function for rows */\r\n transform?: (obj: Record<string, any>, index: number) => any;\r\n}\r\n\r\nexport interface NdjsonToCsvStreamOptions {\r\n /** Delimiter for CSV output (default: ',') */\r\n delimiter?: string;\r\n /** Include headers row (default: true) */\r\n includeHeaders?: boolean;\r\n /** Rename column headers { oldKey: newKey } */\r\n renameMap?: Record<string, string>;\r\n /** Maximum number of records to process */\r\n maxRecords?: number;\r\n /** Prevent CSV injection attacks by escaping formulas (default: true) */\r\n preventCsvInjection?: boolean;\r\n /** Ensure RFC 4180 compliance (proper quoting, line endings) (default: true) */\r\n rfc4180Compliant?: boolean;\r\n /** JSON schema for validation and formatting */\r\n schema?: Record<string, any>;\r\n /** Custom transform function for each row */\r\n transform?: (row: Record<string, any>) => Record<string, any>;\r\n /** Add UTF-8 BOM for Excel compatibility (default: true) */\r\n addBOM?: boolean;\r\n}\r\n\r\n// TSV интерфейсы\r\nexport interface TsvOptions {\r\n /** Whether TSV has headers row (default: true) */\r\n hasHeaders?: boolean;\r\n /** Trim whitespace from values (default: true) */\r\n trim?: boolean;\r\n /** Parse numeric values (default: false) */\r\n parseNumbers?: boolean;\r\n /** Parse boolean values (default: false) */\r\n parseBooleans?: boolean;\r\n /** Maximum number of rows to process */\r\n maxRows?: number;\r\n /** JSON schema for validation and formatting */\r\n schema?: Record<string, any>;\r\n /** Custom transform function for each row */\r\n transform?: (row: Record<string, any>) => Record<string, any>;\r\n}\r\n\r\nexport interface TsvValidationResult {\r\n /** Whether the content is valid TSV */\r\n isValid: boolean;\r\n /** Number of rows detected */\r\n rowCount: number;\r\n /** Number of columns (if consistent) */\r\n columnCount?: number;\r\n /** Error message if invalid */\r\n error?: string;\r\n /** Line number where error occurred */\r\n errorLine?: number;\r\n}\r\n\r\nexport interface ValidateTsvOptions {\r\n /** Maximum number of rows to check */\r\n maxRows?: number;\r\n /** Whether to check for consistent column count */\r\n checkConsistency?: boolean;\r\n /** Whether to validate TSV format strictly */\r\n strict?: boolean;\r\n}\r\n\r\n// Worker интерфейсы для многопоточной обработки\r\nexport interface WorkerTask<T = any, R = any> {\r\n id: string;\r\n data: T;\r\n type: string;\r\n options?: Record<string, any>;\r\n}\r\n\r\nexport interface WorkerResult<R = any> {\r\n id: string;\r\n result: R;\r\n error?: Error;\r\n duration: number;\r\n}\r\n\r\nexport interface WorkerPoolStats {\r\n totalWorkers: number;\r\n activeWorkers: number;\r\n idleWorkers: number;\r\n totalTasks: number;\r\n completedTasks: number;\r\n failedTasks: number;\r\n averageTaskDuration: number;\r\n memoryUsage?: NodeJS.MemoryUsage;\r\n}\r\n\r\n// Асинхронные интерфейсы\r\nexport interface AsyncJsonToCsvOptions extends JsonToCsvOptions {\r\n /** Use worker threads for processing (default: auto-detect based on data size) */\r\n useWorkers?: boolean;\r\n /** Number of worker threads to use (default: CPU cores - 1) */\r\n workerCount?: number;\r\n /** Size of data chunks for parallel processing */\r\n chunkSize?: number;\r\n /** Progress callback function */\r\n onProgress?: (progress: { processed: number; total: number; percentage: number }) => void;\r\n}\r\n\r\nexport interface AsyncCsvToJsonOptions extends CsvToJsonOptions {\r\n /** Use worker threads for processing (default: auto-detect based on data size) */\r\n useWorkers?: boolean;\r\n /** Number of worker threads to use (default: CPU cores - 1) */\r\n workerCount?: number;\r\n /** Size of data chunks for parallel processing */\r\n chunkSize?: number;\r\n /** Progress callback function */\r\n onProgress?: (progress: { processed: number; total: number; percentage: number }) => void;\r\n}\r\n\r\n// Утилитарные типы\r\nexport type PreprocessOptions = {\r\n flatten?: boolean;\r\n flattenSeparator?: string;\r\n flattenMaxDepth?: number;\r\n arrayHandling?: 'stringify' | 'join' | 'expand';\r\n};\r\n\r\nexport type DeepUnwrapOptions = {\r\n maxDepth?: number;\r\n preserveArrays?: boolean;\r\n};\r\n\r\n// Экспорт всех интерфейсов\r\n// Примечание: Типы ошибок экспортируются из errors.ts\r\n"]}