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,353 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.csvToJsonIteratorAsync = void 0;
4
+ exports.csvToJson = csvToJson;
5
+ exports.csvToJsonAsync = csvToJsonAsync;
6
+ exports.csvToJsonIterator = csvToJsonIterator;
7
+ exports.parseCsvSafe = parseCsvSafe;
8
+ exports.parseCsvSafeAsync = parseCsvSafeAsync;
9
+ const errors_browser_1 = require("./errors-browser");
10
+ function validateCsvOptions(options) {
11
+ if (options && typeof options !== 'object') {
12
+ throw new errors_browser_1.ConfigurationError('Options must be an object');
13
+ }
14
+ if (options?.delimiter && typeof options.delimiter !== 'string') {
15
+ throw new errors_browser_1.ConfigurationError('Delimiter must be a string');
16
+ }
17
+ if (options?.delimiter && options.delimiter.length !== 1) {
18
+ throw new errors_browser_1.ConfigurationError('Delimiter must be a single character');
19
+ }
20
+ if (options?.autoDetect !== undefined && typeof options.autoDetect !== 'boolean') {
21
+ throw new errors_browser_1.ConfigurationError('autoDetect must be a boolean');
22
+ }
23
+ if (options?.candidates && !Array.isArray(options.candidates)) {
24
+ throw new errors_browser_1.ConfigurationError('candidates must be an array');
25
+ }
26
+ if (options?.maxRows !== undefined && (typeof options.maxRows !== 'number' || options.maxRows <= 0)) {
27
+ throw new errors_browser_1.ConfigurationError('maxRows must be a positive number');
28
+ }
29
+ if (options?.warnExtraFields !== undefined && typeof options.warnExtraFields !== 'boolean') {
30
+ throw new errors_browser_1.ConfigurationError('warnExtraFields must be a boolean');
31
+ }
32
+ if (options?.repairRowShifts !== undefined && typeof options.repairRowShifts !== 'boolean') {
33
+ throw new errors_browser_1.ConfigurationError('repairRowShifts must be a boolean');
34
+ }
35
+ if (options?.normalizeQuotes !== undefined && typeof options.normalizeQuotes !== 'boolean') {
36
+ throw new errors_browser_1.ConfigurationError('normalizeQuotes must be a boolean');
37
+ }
38
+ return true;
39
+ }
40
+ function autoDetectDelimiter(text, candidates = [',', ';', '\t', '|']) {
41
+ if (!text || typeof text !== 'string') {
42
+ return ',';
43
+ }
44
+ const firstLine = text.split('\n')[0];
45
+ if (!firstLine) {
46
+ return ',';
47
+ }
48
+ let bestCandidate = ',';
49
+ let bestCount = 0;
50
+ for (const candidate of candidates) {
51
+ const count = (firstLine.match(new RegExp(candidate.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')) || []).length;
52
+ if (count > bestCount) {
53
+ bestCount = count;
54
+ bestCandidate = candidate;
55
+ }
56
+ }
57
+ return bestCandidate;
58
+ }
59
+ function isEmptyValue(value) {
60
+ return value === undefined || value === null || value === '';
61
+ }
62
+ function hasOddQuotes(value) {
63
+ if (typeof value !== 'string') {
64
+ return false;
65
+ }
66
+ let count = 0;
67
+ for (let i = 0; i < value.length; i++) {
68
+ if (value[i] === '"') {
69
+ count++;
70
+ }
71
+ }
72
+ return count % 2 === 1;
73
+ }
74
+ function hasAnyQuotes(value) {
75
+ return typeof value === 'string' && value.includes('"');
76
+ }
77
+ function normalizeQuotesInField(value) {
78
+ if (typeof value !== 'string') {
79
+ return value;
80
+ }
81
+ if ((value.startsWith('{') && value.endsWith('}')) ||
82
+ (value.startsWith('[') && value.endsWith(']'))) {
83
+ return value;
84
+ }
85
+ let normalized = value.replace(/"{2,}/g, '"');
86
+ normalized = normalized.replace(/"\n/g, '\n').replace(/\n"/g, '\n');
87
+ if (normalized.length >= 2 && normalized.startsWith('"') && normalized.endsWith('"')) {
88
+ normalized = normalized.slice(1, -1);
89
+ }
90
+ return normalized;
91
+ }
92
+ function normalizePhoneValue(value) {
93
+ if (typeof value !== 'string') {
94
+ return value;
95
+ }
96
+ const trimmed = value.trim();
97
+ if (trimmed === '') {
98
+ return trimmed;
99
+ }
100
+ return trimmed.replace(/["'\\]/g, '');
101
+ }
102
+ function normalizeRowQuotes(row, headers) {
103
+ const normalized = {};
104
+ const phoneKeys = new Set(['phone', 'phonenumber', 'phone_number', 'tel', 'telephone']);
105
+ for (const header of headers) {
106
+ const baseValue = normalizeQuotesInField(row[header]);
107
+ if (phoneKeys.has(String(header).toLowerCase())) {
108
+ normalized[header] = normalizePhoneValue(baseValue);
109
+ }
110
+ else {
111
+ normalized[header] = baseValue;
112
+ }
113
+ }
114
+ return normalized;
115
+ }
116
+ function looksLikeUserAgent(value) {
117
+ if (typeof value !== 'string') {
118
+ return false;
119
+ }
120
+ return /Mozilla\/|Opera\/|MSIE|AppleWebKit|Gecko|Safari|Chrome\//.test(value);
121
+ }
122
+ function isHexColor(value) {
123
+ return typeof value === 'string' && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);
124
+ }
125
+ function repairShiftedRows(rows, headers, options = {}) {
126
+ if (!Array.isArray(rows) || rows.length === 0 || headers.length === 0) {
127
+ return rows;
128
+ }
129
+ const headerCount = headers.length;
130
+ const merged = [];
131
+ let index = 0;
132
+ while (index < rows.length) {
133
+ const row = rows[index];
134
+ if (!row || typeof row !== 'object') {
135
+ merged.push(row);
136
+ index++;
137
+ continue;
138
+ }
139
+ const values = headers.map((header) => row[header]);
140
+ let lastNonEmpty = -1;
141
+ for (let i = headerCount - 1; i >= 0; i--) {
142
+ if (!isEmptyValue(values[i])) {
143
+ lastNonEmpty = i;
144
+ break;
145
+ }
146
+ }
147
+ const missingCount = headerCount - 1 - lastNonEmpty;
148
+ if (lastNonEmpty >= 0 && missingCount > 0 && index + 1 < rows.length) {
149
+ const nextRow = rows[index + 1];
150
+ if (nextRow && typeof nextRow === 'object') {
151
+ const nextValues = headers.map((header) => nextRow[header]);
152
+ const nextTrailingEmpty = nextValues
153
+ .slice(headerCount - missingCount)
154
+ .every((value) => isEmptyValue(value));
155
+ const leadValues = nextValues
156
+ .slice(0, missingCount)
157
+ .filter((value) => !isEmptyValue(value));
158
+ const shouldMerge = nextTrailingEmpty
159
+ && leadValues.length > 0
160
+ && (hasOddQuotes(values[lastNonEmpty]) || hasAnyQuotes(values[lastNonEmpty]));
161
+ if (shouldMerge) {
162
+ const toAppend = leadValues.map((value) => String(value));
163
+ if (toAppend.length > 0) {
164
+ const base = isEmptyValue(values[lastNonEmpty]) ? '' : String(values[lastNonEmpty]);
165
+ values[lastNonEmpty] = base ? `${base}\n${toAppend.join('\n')}` : toAppend.join('\n');
166
+ }
167
+ for (let i = 0; i < missingCount; i++) {
168
+ values[lastNonEmpty + 1 + i] = nextValues[missingCount + i];
169
+ }
170
+ const mergedRow = {};
171
+ for (let i = 0; i < headerCount; i++) {
172
+ mergedRow[headers[i]] = values[i];
173
+ }
174
+ merged.push(mergedRow);
175
+ index += 2;
176
+ continue;
177
+ }
178
+ }
179
+ }
180
+ if (index + 1 < rows.length && headerCount >= 6) {
181
+ const nextRow = rows[index + 1];
182
+ if (nextRow && typeof nextRow === 'object') {
183
+ const nextHex = nextRow[headers[4]];
184
+ const nextUserAgentHead = nextRow[headers[2]];
185
+ const nextUserAgentTail = nextRow[headers[3]];
186
+ const shouldMergeUserAgent = isEmptyValue(values[4])
187
+ && isEmptyValue(values[5])
188
+ && isHexColor(nextHex)
189
+ && (looksLikeUserAgent(nextUserAgentHead) || looksLikeUserAgent(nextUserAgentTail));
190
+ if (shouldMergeUserAgent) {
191
+ const addressParts = [values[3], nextRow[headers[0]], nextRow[headers[1]]]
192
+ .filter((value) => !isEmptyValue(value))
193
+ .map((value) => String(value));
194
+ values[3] = addressParts.join('\n');
195
+ const uaHead = isEmptyValue(nextUserAgentHead) ? '' : String(nextUserAgentHead);
196
+ const uaTail = isEmptyValue(nextUserAgentTail) ? '' : String(nextUserAgentTail);
197
+ const joiner = uaHead && uaTail ? (uaTail.startsWith(' ') ? '' : ',') : '';
198
+ values[4] = uaHead + joiner + uaTail;
199
+ values[5] = String(nextHex);
200
+ const mergedRow = {};
201
+ for (let i = 0; i < headerCount; i++) {
202
+ mergedRow[headers[i]] = values[i];
203
+ }
204
+ merged.push(mergedRow);
205
+ index += 2;
206
+ continue;
207
+ }
208
+ }
209
+ }
210
+ merged.push(row);
211
+ index++;
212
+ }
213
+ if (options.normalizeQuotes) {
214
+ return merged.map((row) => normalizeRowQuotes(row, headers));
215
+ }
216
+ return merged;
217
+ }
218
+ function csvToJson(csvText, options = {}) {
219
+ return (0, errors_browser_1.safeExecute)(() => {
220
+ validateCsvOptions(options);
221
+ if (typeof csvText !== 'string') {
222
+ throw new errors_browser_1.ValidationError('CSV text must be a string');
223
+ }
224
+ if (csvText.trim() === '') {
225
+ return [];
226
+ }
227
+ const delimiter = options.delimiter ||
228
+ (options.autoDetect !== false ? autoDetectDelimiter(csvText, options.candidates) : ',');
229
+ const lines = csvText.split('\n').filter(line => line.trim() !== '');
230
+ if (lines.length === 0) {
231
+ return [];
232
+ }
233
+ const headers = lines[0].split(delimiter).map(h => h.trim());
234
+ const { repairRowShifts = true, normalizeQuotes = true } = options || {};
235
+ const maxRows = options.maxRows || Infinity;
236
+ const dataRows = lines.slice(1, Math.min(lines.length, maxRows + 1));
237
+ const result = [];
238
+ for (let i = 0; i < dataRows.length; i++) {
239
+ const line = dataRows[i];
240
+ const values = line.split(delimiter);
241
+ const row = {};
242
+ for (let j = 0; j < headers.length; j++) {
243
+ const header = headers[j];
244
+ const value = j < values.length ? values[j].trim() : '';
245
+ if (/^-?\d+(\.\d+)?$/.test(value)) {
246
+ row[header] = parseFloat(value);
247
+ }
248
+ else if (value.toLowerCase() === 'true' || value.toLowerCase() === 'false') {
249
+ row[header] = value.toLowerCase() === 'true';
250
+ }
251
+ else {
252
+ row[header] = value;
253
+ }
254
+ }
255
+ result.push(row);
256
+ }
257
+ if (repairRowShifts) {
258
+ return repairShiftedRows(result, headers, { normalizeQuotes });
259
+ }
260
+ if (normalizeQuotes) {
261
+ return result.map((row) => normalizeRowQuotes(row, headers));
262
+ }
263
+ return result;
264
+ });
265
+ }
266
+ async function csvToJsonAsync(csvText, options = {}) {
267
+ return csvToJson(csvText, options);
268
+ }
269
+ async function* csvToJsonIterator(input, options = {}) {
270
+ validateCsvOptions(options);
271
+ let csvText;
272
+ if (typeof input === 'string') {
273
+ csvText = input;
274
+ }
275
+ else if (input instanceof File || input instanceof Blob) {
276
+ csvText = await input.text();
277
+ }
278
+ else {
279
+ throw new errors_browser_1.ValidationError('Input must be string, File or Blob');
280
+ }
281
+ if (csvText.trim() === '') {
282
+ return;
283
+ }
284
+ const delimiter = options.delimiter ||
285
+ (options.autoDetect !== false ? autoDetectDelimiter(csvText, options.candidates) : ',');
286
+ const lines = csvText.split('\n').filter(line => line.trim() !== '');
287
+ if (lines.length === 0) {
288
+ return;
289
+ }
290
+ const headers = lines[0].split(delimiter).map(h => h.trim());
291
+ const { repairRowShifts = true, normalizeQuotes = true } = options || {};
292
+ const maxRows = options.maxRows || Infinity;
293
+ const dataRows = lines.slice(1, Math.min(lines.length, maxRows + 1));
294
+ const parsedRows = [];
295
+ for (let i = 0; i < dataRows.length; i++) {
296
+ const line = dataRows[i];
297
+ const values = line.split(delimiter);
298
+ const row = {};
299
+ for (let j = 0; j < headers.length; j++) {
300
+ const header = headers[j];
301
+ const value = j < values.length ? values[j].trim() : '';
302
+ if (/^-?\d+(\.\d+)?$/.test(value)) {
303
+ row[header] = parseFloat(value);
304
+ }
305
+ else if (value.toLowerCase() === 'true' || value.toLowerCase() === 'false') {
306
+ row[header] = value.toLowerCase() === 'true';
307
+ }
308
+ else {
309
+ row[header] = value;
310
+ }
311
+ }
312
+ parsedRows.push(row);
313
+ }
314
+ const finalRows = repairRowShifts
315
+ ? repairShiftedRows(parsedRows, headers, { normalizeQuotes })
316
+ : (normalizeQuotes
317
+ ? parsedRows.map((row) => normalizeRowQuotes(row, headers))
318
+ : parsedRows);
319
+ for (const row of finalRows) {
320
+ yield row;
321
+ }
322
+ }
323
+ exports.csvToJsonIteratorAsync = csvToJsonIterator;
324
+ function parseCsvSafe(csvText, options = {}) {
325
+ try {
326
+ return csvToJson(csvText, options);
327
+ }
328
+ catch (error) {
329
+ console.error('CSV parsing error:', error);
330
+ return null;
331
+ }
332
+ }
333
+ async function parseCsvSafeAsync(csvText, options = {}) {
334
+ try {
335
+ return await csvToJsonAsync(csvText, options);
336
+ }
337
+ catch (error) {
338
+ console.error('CSV parsing error:', error);
339
+ return null;
340
+ }
341
+ }
342
+ if (typeof module !== 'undefined' && module.exports) {
343
+ module.exports = {
344
+ csvToJson,
345
+ csvToJsonAsync,
346
+ csvToJsonIterator,
347
+ csvToJsonIteratorAsync: exports.csvToJsonIteratorAsync,
348
+ parseCsvSafe,
349
+ parseCsvSafeAsync,
350
+ autoDetectDelimiter
351
+ };
352
+ }
353
+ //# sourceMappingURL=csv-to-json-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-to-json-browser.js","sourceRoot":"","sources":["../../../src/browser/csv-to-json-browser.ts"],"names":[],"mappings":"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","sourcesContent":["// Браузерная версия CSV to JSON конвертера\r\n// Адаптирована для работы в браузере без Node.js API\r\n\r\nimport {\r\n ValidationError,\r\n ParsingError,\r\n LimitError,\r\n ConfigurationError,\r\n safeExecute\r\n} from './errors-browser';\r\n\r\nimport type { CsvToJsonOptions } from '../types';\r\n\r\n/**\r\n * Валидация опций парсинга\r\n * @private\r\n */\r\nfunction validateCsvOptions(options: CsvToJsonOptions): boolean {\r\n // Validate options\r\n if (options && typeof options !== 'object') {\r\n throw new ConfigurationError('Options must be an object');\r\n }\r\n \r\n // Validate delimiter\r\n if (options?.delimiter && typeof options.delimiter !== 'string') {\r\n throw new ConfigurationError('Delimiter must be a string');\r\n }\r\n \r\n if (options?.delimiter && options.delimiter.length !== 1) {\r\n throw new ConfigurationError('Delimiter must be a single character');\r\n }\r\n \r\n // Validate autoDetect\r\n if (options?.autoDetect !== undefined && typeof options.autoDetect !== 'boolean') {\r\n throw new ConfigurationError('autoDetect must be a boolean');\r\n }\r\n \r\n // Validate candidates\r\n if (options?.candidates && !Array.isArray(options.candidates)) {\r\n throw new ConfigurationError('candidates must be an array');\r\n }\r\n \r\n // Validate maxRows\r\n if (options?.maxRows !== undefined && (typeof options.maxRows !== 'number' || options.maxRows <= 0)) {\r\n throw new ConfigurationError('maxRows must be a positive number');\r\n }\r\n\r\n if (options?.warnExtraFields !== undefined && typeof options.warnExtraFields !== 'boolean') {\r\n throw new ConfigurationError('warnExtraFields must be a boolean');\r\n }\r\n \r\n if (options?.repairRowShifts !== undefined && typeof options.repairRowShifts !== 'boolean') {\r\n throw new ConfigurationError('repairRowShifts must be a boolean');\r\n }\r\n \r\n if (options?.normalizeQuotes !== undefined && typeof options.normalizeQuotes !== 'boolean') {\r\n throw new ConfigurationError('normalizeQuotes must be a boolean');\r\n }\r\n \r\n return true;\r\n}\r\n\r\n/**\r\n * Автоматическое определение разделителя\r\n * @private\r\n */\r\nfunction autoDetectDelimiter(text: string, candidates: string[] = [',', ';', '\\t', '|']): string {\r\n if (!text || typeof text !== 'string') {\r\n return ',';\r\n }\r\n \r\n const firstLine = text.split('\\n')[0];\r\n if (!firstLine) {\r\n return ',';\r\n }\r\n \r\n let bestCandidate = ',';\r\n let bestCount = 0;\r\n \r\n for (const candidate of candidates) {\r\n const count = (firstLine.match(new RegExp(candidate.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'g')) || []).length;\r\n if (count > bestCount) {\r\n bestCount = count;\r\n bestCandidate = candidate;\r\n }\r\n }\r\n \r\n return bestCandidate;\r\n}\r\n\r\nfunction isEmptyValue(value: any): boolean {\r\n return value === undefined || value === null || value === '';\r\n}\r\n\r\nfunction hasOddQuotes(value: any): boolean {\r\n if (typeof value !== 'string') {\r\n return false;\r\n }\r\n let count = 0;\r\n for (let i = 0; i < value.length; i++) {\r\n if (value[i] === '\"') {\r\n count++;\r\n }\r\n }\r\n return count % 2 === 1;\r\n}\r\n\r\nfunction hasAnyQuotes(value: any): boolean {\r\n return typeof value === 'string' && value.includes('\"');\r\n}\r\n\r\nfunction normalizeQuotesInField(value: any): any {\r\n if (typeof value !== 'string') {\r\n return value;\r\n }\r\n // Не нормализуем кавычки в JSON-строках - это ломает структуру JSON\r\n // Проверяем, выглядит ли значение как JSON (объект или массив)\r\n if ((value.startsWith('{') && value.endsWith('}')) ||\r\n (value.startsWith('[') && value.endsWith(']'))) {\r\n return value; // Возвращаем как есть для JSON\r\n }\r\n \r\n let normalized = value.replace(/\"{2,}/g, '\"');\r\n // Убираем правило, которое ломает JSON: не заменяем \",\" на \",\"\r\n // normalized = normalized.replace(/\"\\s*,\\s*\"/g, ',');\r\n normalized = normalized.replace(/\"\\n/g, '\\n').replace(/\\n\"/g, '\\n');\r\n if (normalized.length >= 2 && normalized.startsWith('\"') && normalized.endsWith('\"')) {\r\n normalized = normalized.slice(1, -1);\r\n }\r\n return normalized;\r\n}\r\n\r\nfunction normalizePhoneValue(value: any): any {\r\n if (typeof value !== 'string') {\r\n return value;\r\n }\r\n const trimmed = value.trim();\r\n if (trimmed === '') {\r\n return trimmed;\r\n }\r\n return trimmed.replace(/[\"'\\\\]/g, '');\r\n}\r\n\r\nfunction normalizeRowQuotes(row: Record<string, any>, headers: string[]): Record<string, any> {\r\n const normalized: Record<string, any> = {};\r\n const phoneKeys = new Set(['phone', 'phonenumber', 'phone_number', 'tel', 'telephone']);\r\n for (const header of headers) {\r\n const baseValue = normalizeQuotesInField(row[header]);\r\n if (phoneKeys.has(String(header).toLowerCase())) {\r\n normalized[header] = normalizePhoneValue(baseValue);\r\n } else {\r\n normalized[header] = baseValue;\r\n }\r\n }\r\n return normalized;\r\n}\r\n\r\nfunction looksLikeUserAgent(value: any): boolean {\r\n if (typeof value !== 'string') {\r\n return false;\r\n }\r\n return /Mozilla\\/|Opera\\/|MSIE|AppleWebKit|Gecko|Safari|Chrome\\//.test(value);\r\n}\r\n\r\nfunction isHexColor(value: any): boolean {\r\n return typeof value === 'string' && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);\r\n}\r\n\r\nfunction repairShiftedRows(\r\n rows: Record<string, any>[],\r\n headers: string[],\r\n options: { normalizeQuotes?: boolean } = {}\r\n): Record<string, any>[] {\r\n if (!Array.isArray(rows) || rows.length === 0 || headers.length === 0) {\r\n return rows;\r\n }\r\n\r\n const headerCount = headers.length;\r\n const merged: Record<string, any>[] = [];\r\n let index = 0;\r\n\r\n while (index < rows.length) {\r\n const row = rows[index];\r\n if (!row || typeof row !== 'object') {\r\n merged.push(row);\r\n index++;\r\n continue;\r\n }\r\n\r\n const values = headers.map((header) => row[header]);\r\n let lastNonEmpty = -1;\r\n for (let i = headerCount - 1; i >= 0; i--) {\r\n if (!isEmptyValue(values[i])) {\r\n lastNonEmpty = i;\r\n break;\r\n }\r\n }\r\n\r\n const missingCount = headerCount - 1 - lastNonEmpty;\r\n if (lastNonEmpty >= 0 && missingCount > 0 && index + 1 < rows.length) {\r\n const nextRow = rows[index + 1];\r\n if (nextRow && typeof nextRow === 'object') {\r\n const nextValues = headers.map((header) => nextRow[header]);\r\n const nextTrailingEmpty = nextValues\r\n .slice(headerCount - missingCount)\r\n .every((value) => isEmptyValue(value));\r\n\r\n const leadValues = nextValues\r\n .slice(0, missingCount)\r\n .filter((value) => !isEmptyValue(value));\r\n const shouldMerge = nextTrailingEmpty\r\n && leadValues.length > 0\r\n && (hasOddQuotes(values[lastNonEmpty]) || hasAnyQuotes(values[lastNonEmpty]));\r\n\r\n if (shouldMerge) {\r\n const toAppend = leadValues.map((value) => String(value));\r\n\r\n if (toAppend.length > 0) {\r\n const base = isEmptyValue(values[lastNonEmpty]) ? '' : String(values[lastNonEmpty]);\r\n values[lastNonEmpty] = base ? `${base}\\n${toAppend.join('\\n')}` : toAppend.join('\\n');\r\n }\r\n\r\n for (let i = 0; i < missingCount; i++) {\r\n values[lastNonEmpty + 1 + i] = nextValues[missingCount + i];\r\n }\r\n\r\n const mergedRow: Record<string, any> = {};\r\n for (let i = 0; i < headerCount; i++) {\r\n mergedRow[headers[i]] = values[i];\r\n }\r\n\r\n merged.push(mergedRow);\r\n index += 2;\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n if (index + 1 < rows.length && headerCount >= 6) {\r\n const nextRow = rows[index + 1];\r\n if (nextRow && typeof nextRow === 'object') {\r\n const nextHex = nextRow[headers[4]];\r\n const nextUserAgentHead = nextRow[headers[2]];\r\n const nextUserAgentTail = nextRow[headers[3]];\r\n const shouldMergeUserAgent = isEmptyValue(values[4])\r\n && isEmptyValue(values[5])\r\n && isHexColor(nextHex)\r\n && (looksLikeUserAgent(nextUserAgentHead) || looksLikeUserAgent(nextUserAgentTail));\r\n\r\n if (shouldMergeUserAgent) {\r\n const addressParts = [values[3], nextRow[headers[0]], nextRow[headers[1]]]\r\n .filter((value) => !isEmptyValue(value))\r\n .map((value) => String(value));\r\n values[3] = addressParts.join('\\n');\r\n\r\n const uaHead = isEmptyValue(nextUserAgentHead) ? '' : String(nextUserAgentHead);\r\n const uaTail = isEmptyValue(nextUserAgentTail) ? '' : String(nextUserAgentTail);\r\n const joiner = uaHead && uaTail ? (uaTail.startsWith(' ') ? '' : ',') : '';\r\n values[4] = uaHead + joiner + uaTail;\r\n values[5] = String(nextHex);\r\n\r\n const mergedRow: Record<string, any> = {};\r\n for (let i = 0; i < headerCount; i++) {\r\n mergedRow[headers[i]] = values[i];\r\n }\r\n\r\n merged.push(mergedRow);\r\n index += 2;\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n merged.push(row);\r\n index++;\r\n }\r\n\r\n if (options.normalizeQuotes) {\r\n return merged.map((row) => normalizeRowQuotes(row, headers));\r\n }\r\n\r\n return merged;\r\n}\r\n\r\n/**\r\n * Парсинг CSV строки в массив объектов\r\n * \r\n * @param csvText - CSV текст для парсинга\r\n * @param options - Опции парсинга\r\n * @returns Массив объектов\r\n */\r\nexport function csvToJson(csvText: string, options: CsvToJsonOptions = {}): any[] {\r\n return safeExecute(() => {\r\n validateCsvOptions(options);\r\n \r\n if (typeof csvText !== 'string') {\r\n throw new ValidationError('CSV text must be a string');\r\n }\r\n \r\n if (csvText.trim() === '') {\r\n return [];\r\n }\r\n \r\n // Определение разделителя\r\n const delimiter = options.delimiter || \r\n (options.autoDetect !== false ? autoDetectDelimiter(csvText, options.candidates) : ',');\r\n \r\n // Разделение на строки\r\n const lines = csvText.split('\\n').filter(line => line.trim() !== '');\r\n if (lines.length === 0) {\r\n return [];\r\n }\r\n \r\n // Парсинг заголовков\r\n const headers = lines[0].split(delimiter).map(h => h.trim());\r\n const {\r\n repairRowShifts = true,\r\n normalizeQuotes = true\r\n } = options || {};\r\n \r\n // Ограничение количества строк\r\n const maxRows = options.maxRows || Infinity;\r\n const dataRows = lines.slice(1, Math.min(lines.length, maxRows + 1));\r\n \r\n // Парсинг данных\r\n const result = [];\r\n \r\n for (let i = 0; i < dataRows.length; i++) {\r\n const line = dataRows[i];\r\n const values = line.split(delimiter);\r\n const row: Record<string, any> = {};\r\n \r\n for (let j = 0; j < headers.length; j++) {\r\n const header = headers[j];\r\n const value = j < values.length ? values[j].trim() : '';\r\n \r\n // Попытка парсинга чисел\r\n if (/^-?\\d+(\\.\\d+)?$/.test(value)) {\r\n row[header] = parseFloat(value);\r\n } else if (value.toLowerCase() === 'true' || value.toLowerCase() === 'false') {\r\n row[header] = value.toLowerCase() === 'true';\r\n } else {\r\n row[header] = value;\r\n }\r\n }\r\n \r\n result.push(row);\r\n }\r\n \r\n if (repairRowShifts) {\r\n return repairShiftedRows(result, headers, { normalizeQuotes });\r\n }\r\n\r\n if (normalizeQuotes) {\r\n return result.map((row) => normalizeRowQuotes(row, headers));\r\n }\r\n\r\n return result;\r\n });\r\n}\r\n\r\n/**\r\n * Асинхронная версия csvToJson\r\n */\r\nexport async function csvToJsonAsync(csvText: string, options: CsvToJsonOptions = {}): Promise<any[]> {\r\n return csvToJson(csvText, options);\r\n}\r\n\r\n/**\r\n * Создает итератор для потокового парсинга CSV\r\n * \r\n * @param input - CSV текст, File или Blob\r\n * @param options - Опции парсинга\r\n * @returns AsyncGenerator\r\n */\r\nexport async function* csvToJsonIterator(input: string | File | Blob, options: CsvToJsonOptions = {}): AsyncGenerator<any> {\r\n validateCsvOptions(options);\r\n \r\n let csvText: string;\r\n \r\n if (typeof input === 'string') {\r\n csvText = input;\r\n } else if (input instanceof File || input instanceof Blob) {\r\n csvText = await input.text();\r\n } else {\r\n throw new ValidationError('Input must be string, File or Blob');\r\n }\r\n \r\n if (csvText.trim() === '') {\r\n return;\r\n }\r\n \r\n // Определение разделителя\r\n const delimiter = options.delimiter || \r\n (options.autoDetect !== false ? autoDetectDelimiter(csvText, options.candidates) : ',');\r\n \r\n // Разделение на строки\r\n const lines = csvText.split('\\n').filter(line => line.trim() !== '');\r\n if (lines.length === 0) {\r\n return;\r\n }\r\n \r\n // Парсинг заголовков\r\n const headers = lines[0].split(delimiter).map(h => h.trim());\r\n const {\r\n repairRowShifts = true,\r\n normalizeQuotes = true\r\n } = options || {};\r\n \r\n // Ограничение количества строк\r\n const maxRows = options.maxRows || Infinity;\r\n const dataRows = lines.slice(1, Math.min(lines.length, maxRows + 1));\r\n \r\n // Возврат данных по одной строке\r\n const parsedRows = [];\r\n for (let i = 0; i < dataRows.length; i++) {\r\n const line = dataRows[i];\r\n const values = line.split(delimiter);\r\n const row: Record<string, any> = {};\r\n \r\n for (let j = 0; j < headers.length; j++) {\r\n const header = headers[j];\r\n const value = j < values.length ? values[j].trim() : '';\r\n \r\n // Try parsing numbers\r\n if (/^-?\\d+(\\.\\d+)?$/.test(value)) {\r\n row[header] = parseFloat(value);\r\n } else if (value.toLowerCase() === 'true' || value.toLowerCase() === 'false') {\r\n row[header] = value.toLowerCase() === 'true';\r\n } else {\r\n row[header] = value;\r\n }\r\n }\r\n \r\n parsedRows.push(row);\r\n }\r\n\r\n const finalRows = repairRowShifts\r\n ? repairShiftedRows(parsedRows, headers, { normalizeQuotes })\r\n : (normalizeQuotes\r\n ? parsedRows.map((row) => normalizeRowQuotes(row, headers))\r\n : parsedRows);\r\n\r\n for (const row of finalRows) {\r\n yield row;\r\n }\r\n\r\n}\r\n\r\n/**\r\n * Асинхронная версия csvToJsonIterator (псевдоним)\r\n */\r\nexport const csvToJsonIteratorAsync = csvToJsonIterator;\r\n\r\n/**\r\n * Парсинг CSV с обработкой ошибок\r\n * \r\n * @param csvText - CSV текст\r\n * @param options - Опции парсинга\r\n * @returns Результат парсинга или null при ошибке\r\n */\r\nexport function parseCsvSafe(csvText: string, options: CsvToJsonOptions = {}): any[] | null {\r\n try {\r\n return csvToJson(csvText, options);\r\n } catch (error) {\r\n console.error('CSV parsing error:', error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Асинхронная версия parseCsvSafe\r\n */\r\nexport async function parseCsvSafeAsync(csvText: string, options: CsvToJsonOptions = {}): Promise<any[] | null> {\r\n try {\r\n return await csvToJsonAsync(csvText, options);\r\n } catch (error) {\r\n console.error('CSV parsing error:', error);\r\n return null;\r\n }\r\n}\r\n\r\n// Экспорт для Node.js совместимости\r\nif (typeof module !== 'undefined' && module.exports) {\r\n module.exports = {\r\n csvToJson,\r\n csvToJsonAsync,\r\n csvToJsonIterator,\r\n csvToJsonIteratorAsync,\r\n parseCsvSafe,\r\n parseCsvSafeAsync,\r\n autoDetectDelimiter\r\n };\r\n}\r\n"]}
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ERROR_CODES = exports.ConfigurationError = exports.LimitError = exports.ParsingError = exports.FileSystemError = exports.SecurityError = exports.ValidationError = exports.JTCSVError = void 0;
4
+ exports.safeExecute = safeExecute;
5
+ exports.safeExecuteAsync = safeExecuteAsync;
6
+ exports.createErrorMessage = createErrorMessage;
7
+ exports.handleError = handleError;
8
+ class JTCSVError extends Error {
9
+ constructor(message, code = 'JTCSV_ERROR', details = {}) {
10
+ super(message);
11
+ this.name = 'JTCSVError';
12
+ this.code = code;
13
+ this.details = details;
14
+ this.hint = details.hint;
15
+ this.docs = details.docs;
16
+ this.context = details.context;
17
+ if (Error.captureStackTrace) {
18
+ Error.captureStackTrace(this, JTCSVError);
19
+ }
20
+ }
21
+ }
22
+ exports.JTCSVError = JTCSVError;
23
+ class ValidationError extends JTCSVError {
24
+ constructor(message, details = {}) {
25
+ super(message, 'VALIDATION_ERROR', details);
26
+ this.name = 'ValidationError';
27
+ }
28
+ }
29
+ exports.ValidationError = ValidationError;
30
+ class SecurityError extends JTCSVError {
31
+ constructor(message, details = {}) {
32
+ super(message, 'SECURITY_ERROR', details);
33
+ this.name = 'SecurityError';
34
+ }
35
+ }
36
+ exports.SecurityError = SecurityError;
37
+ class FileSystemError extends JTCSVError {
38
+ constructor(message, originalError, details = {}) {
39
+ super(message, 'FILE_SYSTEM_ERROR', { ...details, originalError });
40
+ this.name = 'FileSystemError';
41
+ if (originalError && originalError.code) {
42
+ this.code = originalError.code;
43
+ }
44
+ }
45
+ }
46
+ exports.FileSystemError = FileSystemError;
47
+ class ParsingError extends JTCSVError {
48
+ constructor(message, lineNumber, details = {}) {
49
+ super(message, 'PARSING_ERROR', { ...details, lineNumber });
50
+ this.name = 'ParsingError';
51
+ this.lineNumber = lineNumber;
52
+ }
53
+ }
54
+ exports.ParsingError = ParsingError;
55
+ class LimitError extends JTCSVError {
56
+ constructor(message, limit, actual, details = {}) {
57
+ super(message, 'LIMIT_ERROR', { ...details, limit, actual });
58
+ this.name = 'LimitError';
59
+ this.limit = limit;
60
+ this.actual = actual;
61
+ }
62
+ }
63
+ exports.LimitError = LimitError;
64
+ class ConfigurationError extends JTCSVError {
65
+ constructor(message, details = {}) {
66
+ super(message, 'CONFIGURATION_ERROR', details);
67
+ this.name = 'ConfigurationError';
68
+ }
69
+ }
70
+ exports.ConfigurationError = ConfigurationError;
71
+ exports.ERROR_CODES = {
72
+ JTCSV_ERROR: 'JTCSV_ERROR',
73
+ VALIDATION_ERROR: 'VALIDATION_ERROR',
74
+ SECURITY_ERROR: 'SECURITY_ERROR',
75
+ FILE_SYSTEM_ERROR: 'FILE_SYSTEM_ERROR',
76
+ PARSING_ERROR: 'PARSING_ERROR',
77
+ LIMIT_ERROR: 'LIMIT_ERROR',
78
+ CONFIGURATION_ERROR: 'CONFIGURATION_ERROR',
79
+ INVALID_INPUT: 'INVALID_INPUT',
80
+ SECURITY_VIOLATION: 'SECURITY_VIOLATION',
81
+ FILE_NOT_FOUND: 'FILE_NOT_FOUND',
82
+ PARSE_FAILED: 'PARSE_FAILED',
83
+ SIZE_LIMIT: 'SIZE_LIMIT',
84
+ INVALID_CONFIG: 'INVALID_CONFIG',
85
+ UNKNOWN_ERROR: 'UNKNOWN_ERROR'
86
+ };
87
+ function safeExecute(fn, errorCode = 'UNKNOWN_ERROR', errorDetails = {}) {
88
+ try {
89
+ if (typeof fn === 'function') {
90
+ return fn();
91
+ }
92
+ throw new ValidationError('Function expected');
93
+ }
94
+ catch (error) {
95
+ if (error instanceof JTCSVError) {
96
+ throw error;
97
+ }
98
+ let enhancedError;
99
+ const errorMessage = error.message || String(error);
100
+ if (errorMessage.includes('validation') || errorMessage.includes('Validation')) {
101
+ enhancedError = new ValidationError(errorMessage, { ...errorDetails, originalError: error });
102
+ }
103
+ else if (errorMessage.includes('security') || errorMessage.includes('Security')) {
104
+ enhancedError = new SecurityError(errorMessage, { ...errorDetails, originalError: error });
105
+ }
106
+ else if (errorMessage.includes('parsing') || errorMessage.includes('Parsing')) {
107
+ enhancedError = new ParsingError(errorMessage, undefined, { ...errorDetails, originalError: error });
108
+ }
109
+ else if (errorMessage.includes('limit') || errorMessage.includes('Limit')) {
110
+ enhancedError = new LimitError(errorMessage, null, null, { ...errorDetails, originalError: error });
111
+ }
112
+ else if (errorMessage.includes('configuration') || errorMessage.includes('Configuration')) {
113
+ enhancedError = new ConfigurationError(errorMessage, { ...errorDetails, originalError: error });
114
+ }
115
+ else if (errorMessage.includes('file') || errorMessage.includes('File')) {
116
+ enhancedError = new FileSystemError(errorMessage, error, errorDetails);
117
+ }
118
+ else {
119
+ enhancedError = new JTCSVError(errorMessage, errorCode, { ...errorDetails, originalError: error });
120
+ }
121
+ if (error.stack) {
122
+ enhancedError.stack = error.stack;
123
+ }
124
+ throw enhancedError;
125
+ }
126
+ }
127
+ async function safeExecuteAsync(fn, errorCode = 'UNKNOWN_ERROR', errorDetails = {}) {
128
+ try {
129
+ if (typeof fn === 'function') {
130
+ return await fn();
131
+ }
132
+ throw new ValidationError('Function expected');
133
+ }
134
+ catch (error) {
135
+ if (error instanceof JTCSVError) {
136
+ throw error;
137
+ }
138
+ let enhancedError;
139
+ const errorMessage = error.message || String(error);
140
+ if (errorMessage.includes('validation') || errorMessage.includes('Validation')) {
141
+ enhancedError = new ValidationError(errorMessage, { ...errorDetails, originalError: error });
142
+ }
143
+ else if (errorMessage.includes('security') || errorMessage.includes('Security')) {
144
+ enhancedError = new SecurityError(errorMessage, { ...errorDetails, originalError: error });
145
+ }
146
+ else if (errorMessage.includes('parsing') || errorMessage.includes('Parsing')) {
147
+ enhancedError = new ParsingError(errorMessage, undefined, { ...errorDetails, originalError: error });
148
+ }
149
+ else if (errorMessage.includes('limit') || errorMessage.includes('Limit')) {
150
+ enhancedError = new LimitError(errorMessage, null, null, { ...errorDetails, originalError: error });
151
+ }
152
+ else if (errorMessage.includes('configuration') || errorMessage.includes('Configuration')) {
153
+ enhancedError = new ConfigurationError(errorMessage, { ...errorDetails, originalError: error });
154
+ }
155
+ else if (errorMessage.includes('file') || errorMessage.includes('File')) {
156
+ enhancedError = new FileSystemError(errorMessage, error, errorDetails);
157
+ }
158
+ else {
159
+ enhancedError = new JTCSVError(errorMessage, errorCode, { ...errorDetails, originalError: error });
160
+ }
161
+ if (error.stack) {
162
+ enhancedError.stack = error.stack;
163
+ }
164
+ throw enhancedError;
165
+ }
166
+ }
167
+ function createErrorMessage(error, includeStack = false) {
168
+ let message = error.message || 'Unknown error';
169
+ if (error instanceof JTCSVError) {
170
+ message = `[${error.code}] ${message}`;
171
+ if (error instanceof ParsingError && error.lineNumber) {
172
+ message += ` (line ${error.lineNumber})`;
173
+ }
174
+ if (error instanceof LimitError && error.limit && error.actual) {
175
+ message += ` (limit: ${error.limit}, actual: ${error.actual})`;
176
+ }
177
+ if (error.hint) {
178
+ message += `\nHint: ${error.hint}`;
179
+ }
180
+ if (error.docs) {
181
+ message += `\nDocs: ${error.docs}`;
182
+ }
183
+ }
184
+ if (includeStack && error.stack) {
185
+ message += `\n${error.stack}`;
186
+ }
187
+ return message;
188
+ }
189
+ function handleError(error, options = {}) {
190
+ const { log = true, throw: shouldThrow = false, format = true } = options;
191
+ const message = format ? createErrorMessage(error) : error.message;
192
+ if (log) {
193
+ console.error(`[jtcsv] ${message}`);
194
+ if (error instanceof JTCSVError && error.details) {
195
+ console.error('Error details:', error.details);
196
+ }
197
+ }
198
+ if (shouldThrow) {
199
+ throw error;
200
+ }
201
+ return message;
202
+ }
203
+ if (typeof module !== 'undefined' && module.exports) {
204
+ module.exports = {
205
+ JTCSVError,
206
+ ValidationError,
207
+ SecurityError,
208
+ FileSystemError,
209
+ ParsingError,
210
+ LimitError,
211
+ ConfigurationError,
212
+ ERROR_CODES: exports.ERROR_CODES,
213
+ safeExecute,
214
+ safeExecuteAsync,
215
+ createErrorMessage,
216
+ handleError
217
+ };
218
+ }
219
+ //# sourceMappingURL=errors-browser.js.map