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,348 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.predefinedHooks = exports.TransformHooks = void 0;
4
+ const errors_1 = require("../errors");
5
+ class TransformHooks {
6
+ constructor(options) {
7
+ this.hooks = {
8
+ beforeConvert: options?.hooks?.beforeConvert || [],
9
+ afterConvert: options?.hooks?.afterConvert || [],
10
+ perRow: options?.hooks?.perRow || []
11
+ };
12
+ }
13
+ beforeConvert(hook) {
14
+ if (typeof hook !== 'function') {
15
+ throw new errors_1.ValidationError('beforeConvert hook must be a function');
16
+ }
17
+ this.hooks.beforeConvert.push(hook);
18
+ return this;
19
+ }
20
+ afterConvert(hook) {
21
+ if (typeof hook !== 'function') {
22
+ throw new errors_1.ValidationError('afterConvert hook must be a function');
23
+ }
24
+ this.hooks.afterConvert.push(hook);
25
+ return this;
26
+ }
27
+ perRow(hook) {
28
+ if (typeof hook !== 'function') {
29
+ throw new errors_1.ValidationError('perRow hook must be a function');
30
+ }
31
+ this.hooks.perRow.push(hook);
32
+ return this;
33
+ }
34
+ applyBeforeConvert(data, context = {}) {
35
+ let result = data;
36
+ for (const hook of this.hooks.beforeConvert) {
37
+ result = hook(result, context);
38
+ }
39
+ return result;
40
+ }
41
+ async applyBeforeConvertAsync(data, context = {}) {
42
+ let result = data;
43
+ for (const hook of this.hooks.beforeConvert) {
44
+ if (this.isAsyncFunction(hook)) {
45
+ result = await hook(result, context);
46
+ }
47
+ else {
48
+ result = hook(result, context);
49
+ }
50
+ }
51
+ return result;
52
+ }
53
+ applyAfterConvert(data, context = {}) {
54
+ let result = data;
55
+ for (const hook of this.hooks.afterConvert) {
56
+ result = hook(result, context);
57
+ }
58
+ return result;
59
+ }
60
+ async applyAfterConvertAsync(data, context = {}) {
61
+ let result = data;
62
+ for (const hook of this.hooks.afterConvert) {
63
+ if (this.isAsyncFunction(hook)) {
64
+ result = await hook(result, context);
65
+ }
66
+ else {
67
+ result = hook(result, context);
68
+ }
69
+ }
70
+ return result;
71
+ }
72
+ applyPerRow(row, index, context = {}) {
73
+ let result = row;
74
+ for (const hook of this.hooks.perRow) {
75
+ result = hook(result, index, context);
76
+ }
77
+ return result;
78
+ }
79
+ async applyPerRowAsync(row, index, context = {}) {
80
+ let result = row;
81
+ for (const hook of this.hooks.perRow) {
82
+ if (this.isAsyncFunction(hook)) {
83
+ result = await hook(result, index, context);
84
+ }
85
+ else {
86
+ result = hook(result, index, context);
87
+ }
88
+ }
89
+ return result;
90
+ }
91
+ applyAll(data, context = {}) {
92
+ if (!Array.isArray(data)) {
93
+ throw new errors_1.ValidationError('Data must be an array for applyAll');
94
+ }
95
+ let processedData = this.applyBeforeConvert(data, context);
96
+ if (this.hooks.perRow.length > 0) {
97
+ processedData = processedData.map((row, index) => this.applyPerRow(row, index, context));
98
+ }
99
+ return this.applyAfterConvert(processedData, context);
100
+ }
101
+ async applyAllAsync(data, context = {}) {
102
+ if (!Array.isArray(data)) {
103
+ throw new errors_1.ValidationError('Data must be an array for applyAll');
104
+ }
105
+ let processedData = await this.applyBeforeConvertAsync(data, context);
106
+ if (this.hooks.perRow.length > 0) {
107
+ const processedRows = [];
108
+ for (let i = 0; i < processedData.length; i++) {
109
+ const processedRow = await this.applyPerRowAsync(processedData[i], i, context);
110
+ processedRows.push(processedRow);
111
+ }
112
+ processedData = processedRows;
113
+ }
114
+ return await this.applyAfterConvertAsync(processedData, context);
115
+ }
116
+ clone() {
117
+ const cloned = new TransformHooks();
118
+ cloned.hooks = {
119
+ beforeConvert: [...this.hooks.beforeConvert],
120
+ afterConvert: [...this.hooks.afterConvert],
121
+ perRow: [...this.hooks.perRow]
122
+ };
123
+ return cloned;
124
+ }
125
+ clear() {
126
+ this.hooks = {
127
+ beforeConvert: [],
128
+ afterConvert: [],
129
+ perRow: []
130
+ };
131
+ }
132
+ getStats() {
133
+ return {
134
+ beforeConvert: this.hooks.beforeConvert.length,
135
+ afterConvert: this.hooks.afterConvert.length,
136
+ perRow: this.hooks.perRow.length,
137
+ total: this.hooks.beforeConvert.length +
138
+ this.hooks.afterConvert.length +
139
+ this.hooks.perRow.length
140
+ };
141
+ }
142
+ isAsyncFunction(fn) {
143
+ return fn.constructor.name === 'AsyncFunction' ||
144
+ (typeof fn === 'function' && fn.constructor === (async () => { }).constructor);
145
+ }
146
+ }
147
+ exports.TransformHooks = TransformHooks;
148
+ exports.predefinedHooks = {
149
+ filter(predicate) {
150
+ return (data) => {
151
+ if (Array.isArray(data)) {
152
+ return data.filter(predicate);
153
+ }
154
+ return data;
155
+ };
156
+ },
157
+ filterAsync(predicate) {
158
+ return async (data) => {
159
+ if (Array.isArray(data)) {
160
+ const filtered = [];
161
+ for (let i = 0; i < data.length; i++) {
162
+ if (await predicate(data[i], i)) {
163
+ filtered.push(data[i]);
164
+ }
165
+ }
166
+ return filtered;
167
+ }
168
+ return data;
169
+ };
170
+ },
171
+ map(mapper) {
172
+ return (data) => {
173
+ if (Array.isArray(data)) {
174
+ return data.map(mapper);
175
+ }
176
+ return data;
177
+ };
178
+ },
179
+ mapAsync(mapper) {
180
+ return async (data) => {
181
+ if (Array.isArray(data)) {
182
+ const mapped = [];
183
+ for (let i = 0; i < data.length; i++) {
184
+ mapped.push(await mapper(data[i], i));
185
+ }
186
+ return mapped;
187
+ }
188
+ return data;
189
+ };
190
+ },
191
+ sort(compareFn) {
192
+ return (data) => {
193
+ if (Array.isArray(data)) {
194
+ return [...data].sort(compareFn);
195
+ }
196
+ return data;
197
+ };
198
+ },
199
+ limit(limit) {
200
+ return (data) => {
201
+ if (Array.isArray(data)) {
202
+ return data.slice(0, limit);
203
+ }
204
+ return data;
205
+ };
206
+ },
207
+ addMetadata(metadata) {
208
+ return (data, context) => {
209
+ if (Array.isArray(data)) {
210
+ return data.map(item => ({
211
+ ...item,
212
+ _metadata: {
213
+ ...metadata,
214
+ timestamp: new Date().toISOString(),
215
+ context
216
+ }
217
+ }));
218
+ }
219
+ return data;
220
+ };
221
+ },
222
+ transformKeys(keyTransformer) {
223
+ return (data) => {
224
+ if (Array.isArray(data)) {
225
+ return data.map(item => {
226
+ const transformed = {};
227
+ for (const [key, value] of Object.entries(item)) {
228
+ transformed[keyTransformer(key)] = value;
229
+ }
230
+ return transformed;
231
+ });
232
+ }
233
+ return data;
234
+ };
235
+ },
236
+ transformValues(valueTransformer) {
237
+ return (data) => {
238
+ if (Array.isArray(data)) {
239
+ return data.map(item => {
240
+ const transformed = {};
241
+ for (const [key, value] of Object.entries(item)) {
242
+ transformed[key] = valueTransformer(value, key);
243
+ }
244
+ return transformed;
245
+ });
246
+ }
247
+ return data;
248
+ };
249
+ },
250
+ validate(validator, onError = console.error) {
251
+ return (data) => {
252
+ if (Array.isArray(data)) {
253
+ const validData = [];
254
+ const errors = [];
255
+ data.forEach((item, index) => {
256
+ try {
257
+ const isValid = validator(item, index);
258
+ if (isValid) {
259
+ validData.push(item);
260
+ }
261
+ else {
262
+ errors.push({ index, item, reason: 'Validation failed' });
263
+ }
264
+ }
265
+ catch (error) {
266
+ errors.push({ index, item, error: error.message });
267
+ }
268
+ });
269
+ if (errors.length > 0) {
270
+ if (onError.length >= 2) {
271
+ onError('Validation errors', errors);
272
+ }
273
+ else {
274
+ onError(errors);
275
+ }
276
+ }
277
+ return validData;
278
+ }
279
+ return data;
280
+ };
281
+ },
282
+ validateAsync(validator, onError = console.error) {
283
+ return async (data) => {
284
+ if (Array.isArray(data)) {
285
+ const validData = [];
286
+ const errors = [];
287
+ for (let i = 0; i < data.length; i++) {
288
+ try {
289
+ const isValid = await validator(data[i], i);
290
+ if (isValid) {
291
+ validData.push(data[i]);
292
+ }
293
+ else {
294
+ errors.push({ index: i, item: data[i], reason: 'Validation failed' });
295
+ }
296
+ }
297
+ catch (error) {
298
+ errors.push({ index: i, item: data[i], error: error.message });
299
+ }
300
+ }
301
+ if (errors.length > 0) {
302
+ if (onError.length >= 2) {
303
+ onError('Validation errors', errors);
304
+ }
305
+ else {
306
+ onError(errors);
307
+ }
308
+ }
309
+ return validData;
310
+ }
311
+ return data;
312
+ };
313
+ },
314
+ deduplicate(keySelector = JSON.stringify) {
315
+ return (data) => {
316
+ if (Array.isArray(data)) {
317
+ const seen = new Set();
318
+ return data.filter(item => {
319
+ const key = keySelector(item);
320
+ if (seen.has(key)) {
321
+ return false;
322
+ }
323
+ seen.add(key);
324
+ return true;
325
+ });
326
+ }
327
+ return data;
328
+ };
329
+ },
330
+ deduplicateAsync(keySelector = async (item) => JSON.stringify(item)) {
331
+ return async (data) => {
332
+ if (Array.isArray(data)) {
333
+ const seen = new Set();
334
+ const filtered = [];
335
+ for (const item of data) {
336
+ const key = await keySelector(item);
337
+ if (!seen.has(key)) {
338
+ seen.add(key);
339
+ filtered.push(item);
340
+ }
341
+ }
342
+ return filtered;
343
+ }
344
+ return data;
345
+ };
346
+ }
347
+ };
348
+ //# sourceMappingURL=transform-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform-hooks.js","sourceRoot":"","sources":["../../../src/core/transform-hooks.ts"],"names":[],"mappings":";;;AAQA,sCAA4C;AAmB5C,MAAa,cAAc;IAOzB,YAAY,OAA+B;QACzC,IAAI,CAAC,KAAK,GAAG;YACX,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,IAAI,EAAE;YAClD,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,IAAI,EAAE;YAChD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,EAAE;SACrC,CAAC;IACJ,CAAC;IAOD,aAAa,CAAC,IAAsC;QAClD,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,wBAAe,CAAC,uCAAuC,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAOD,YAAY,CAAC,IAAsC;QACjD,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,wBAAe,CAAC,sCAAsC,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAOD,MAAM,CAAC,IAAkD;QACvD,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,wBAAe,CAAC,gCAAgC,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAQD,kBAAkB,CAAmB,IAAO,EAAE,UAAuB,EAAE;QACrE,IAAI,MAAM,GAAQ,IAAI,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YAC5C,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;IAQD,KAAK,CAAC,uBAAuB,CAAmB,IAAO,EAAE,UAAuB,EAAE;QAChF,IAAI,MAAM,GAAQ,IAAI,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,MAAM,GAAG,MAAO,IAA0B,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAI,IAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;IAQD,iBAAiB,CAAmB,IAAO,EAAE,UAAuB,EAAE;QACpE,IAAI,MAAM,GAAQ,IAAI,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YAC3C,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;IAQD,KAAK,CAAC,sBAAsB,CAAmB,IAAO,EAAE,UAAuB,EAAE;QAC/E,IAAI,MAAM,GAAQ,IAAI,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,MAAM,GAAG,MAAO,IAA0B,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAI,IAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;IASD,WAAW,CAAmB,GAAM,EAAE,KAAa,EAAE,UAAuB,EAAE;QAC5E,IAAI,MAAM,GAAQ,GAAG,CAAC;QACtB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;IASD,KAAK,CAAC,gBAAgB,CAAmB,GAAM,EAAE,KAAa,EAAE,UAAuB,EAAE;QACvF,IAAI,MAAM,GAAQ,GAAG,CAAC;QACtB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,MAAM,GAAG,MAAO,IAAgC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC3E,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAI,IAA2B,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;IAQD,QAAQ,CAAmB,IAAS,EAAE,UAAuB,EAAE;QAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,wBAAe,CAAC,oCAAoC,CAAC,CAAC;QAClE,CAAC;QAGD,IAAI,aAAa,GAAU,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAGlE,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,aAAa,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,KAAa,EAAE,EAAE,CAC5D,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CACtC,CAAC;QACJ,CAAC;QAGD,OAAO,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,OAAO,CAAQ,CAAC;IAC/D,CAAC;IAQD,KAAK,CAAC,aAAa,CAAmB,IAAS,EAAE,UAAuB,EAAE;QACxE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,wBAAe,CAAC,oCAAoC,CAAC,CAAC;QAClE,CAAC;QAGD,IAAI,aAAa,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAGtE,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,aAAa,GAAU,EAAE,CAAC;YAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;gBAC/E,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnC,CAAC;YACD,aAAa,GAAG,aAAa,CAAC;QAChC,CAAC;QAGD,OAAO,MAAM,IAAI,CAAC,sBAAsB,CAAC,aAAa,EAAE,OAAO,CAAQ,CAAC;IAC1E,CAAC;IAMD,KAAK;QACH,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACpC,MAAM,CAAC,KAAK,GAAG;YACb,aAAa,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;YAC5C,YAAY,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;YAC1C,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;SAC/B,CAAC;QACF,OAAO,MAAM,CAAC;IAChB,CAAC;IAKD,KAAK;QACH,IAAI,CAAC,KAAK,GAAG;YACX,aAAa,EAAE,EAAE;YACjB,YAAY,EAAE,EAAE;YAChB,MAAM,EAAE,EAAE;SACX,CAAC;IACJ,CAAC;IAMD,QAAQ;QACN,OAAO;YACL,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM;YAC9C,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM;YAC5C,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;YAChC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM;gBAC/B,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM;gBAC9B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;SAChC,CAAC;IACJ,CAAC;IAMO,eAAe,CAAC,EAAO;QAC7B,OAAO,EAAE,CAAC,WAAW,CAAC,IAAI,KAAK,eAAe;YACvC,CAAC,OAAO,EAAE,KAAK,UAAU,IAAI,EAAE,CAAC,WAAW,KAAK,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACvF,CAAC;CACF;AA7PD,wCA6PC;AAKY,QAAA,eAAe,GAAG;IAM7B,MAAM,CAAI,SAA8C;QACtD,OAAO,CAAC,IAAS,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAChC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAOD,WAAW,CAAI,SAAuD;QACpE,OAAO,KAAK,EAAE,IAAS,EAAE,EAAE;YACzB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,QAAQ,GAAQ,EAAE,CAAC;gBACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrC,IAAI,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;wBAChC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;gBACD,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAOD,GAAG,CAAO,MAAqC;QAC7C,OAAO,CAAC,IAAS,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC;YACD,OAAO,IAAW,CAAC;QACrB,CAAC,CAAC;IACJ,CAAC;IAOD,QAAQ,CAAO,MAA8C;QAC3D,OAAO,KAAK,EAAE,IAAS,EAAE,EAAE;YACzB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAQ,EAAE,CAAC;gBACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrC,MAAM,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACxC,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,OAAO,IAAW,CAAC;QACrB,CAAC,CAAC;IACJ,CAAC;IAOD,IAAI,CAAI,SAAkC;QACxC,OAAO,CAAC,IAAS,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACnC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAOD,KAAK,CAAI,KAAa;QACpB,OAAO,CAAC,IAAS,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAOD,WAAW,CAAgC,QAA6B;QACtE,OAAO,CAAC,IAAS,EAAE,OAAqB,EAAE,EAAE;YAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACvB,GAAG,IAAI;oBACP,SAAS,EAAE;wBACT,GAAG,QAAQ;wBACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACnC,OAAO;qBACR;iBACF,CAAC,CAAkC,CAAC;YACvC,CAAC;YACD,OAAO,IAAW,CAAC;QACrB,CAAC,CAAC;IACJ,CAAC;IAOD,aAAa,CAAgC,cAAuC;QAClF,OAAO,CAAC,IAAS,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;oBACrB,MAAM,WAAW,GAAwB,EAAE,CAAC;oBAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;wBAChD,WAAW,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;oBAC3C,CAAC;oBACD,OAAO,WAAW,CAAC;gBACrB,CAAC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAOD,eAAe,CAAgC,gBAAkD;QAC/F,OAAO,CAAC,IAAS,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;oBACrB,MAAM,WAAW,GAAwB,EAAE,CAAC;oBAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;wBAChD,WAAW,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;oBAClD,CAAC;oBACD,OAAO,WAAW,CAAC;gBACrB,CAAC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAQD,QAAQ,CAAI,SAA8C,EAAE,UAA6D,OAAO,CAAC,KAAK;QACpI,OAAO,CAAC,IAAS,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAQ,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAU,EAAE,CAAC;gBAEzB,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBAC3B,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;wBACvC,IAAI,OAAO,EAAE,CAAC;4BACZ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACvB,CAAC;6BAAM,CAAC;4BACN,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;wBAC5D,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAU,EAAE,CAAC;wBACpB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;oBACrD,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;wBACxB,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;oBACvC,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;gBAED,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAQD,aAAa,CAAI,SAAuD,EAAE,UAA6D,OAAO,CAAC,KAAK;QAClJ,OAAO,KAAK,EAAE,IAAS,EAAE,EAAE;YACzB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAQ,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAU,EAAE,CAAC;gBAEzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrC,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAC5C,IAAI,OAAO,EAAE,CAAC;4BACZ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC1B,CAAC;6BAAM,CAAC;4BACN,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;wBACxE,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAU,EAAE,CAAC;wBACpB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;oBACjE,CAAC;gBACH,CAAC;gBAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;wBACxB,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;oBACvC,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;gBAED,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAOD,WAAW,CAAI,cAAmC,IAAI,CAAC,SAAS;QAC9D,OAAO,CAAC,IAAS,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;gBAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;oBACxB,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;oBAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBAClB,OAAO,KAAK,CAAC;oBACf,CAAC;oBACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,IAAI,CAAC;gBACd,CAAC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAOD,gBAAgB,CAAI,cAA4C,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAClG,OAAO,KAAK,EAAE,IAAS,EAAE,EAAE;YACzB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;gBAC/B,MAAM,QAAQ,GAAQ,EAAE,CAAC;gBAEzB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;oBACxB,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;oBACpC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;wBACd,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACtB,CAAC;gBACH,CAAC;gBAED,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["/**\r\n * Transform Hooks System\r\n * Система хуков для трансформации данных перед/после конвертации\r\n * \r\n * @version 2.0.0\r\n * @date 2026-01-29\r\n */\r\n\r\nimport { ValidationError } from '../errors';\r\n\r\nexport interface HookContext {\r\n [key: string]: any;\r\n}\r\n\r\nexport type HookFunction<T = any, R = any> = (data: T, context?: HookContext) => R;\r\nexport type PerRowHookFunction<T = any, R = any> = (row: T, index: number, context?: HookContext) => R;\r\nexport type AsyncHookFunction<T = any, R = any> = (data: T, context?: HookContext) => Promise<R>;\r\nexport type AsyncPerRowHookFunction<T = any, R = any> = (row: T, index: number, context?: HookContext) => Promise<R>;\r\n\r\nexport interface TransformHooksOptions {\r\n hooks?: {\r\n beforeConvert?: Array<HookFunction | AsyncHookFunction>;\r\n afterConvert?: Array<HookFunction | AsyncHookFunction>;\r\n perRow?: Array<PerRowHookFunction | AsyncPerRowHookFunction>;\r\n };\r\n}\r\n\r\nexport class TransformHooks {\r\n private hooks: {\r\n beforeConvert: Array<HookFunction | AsyncHookFunction>;\r\n afterConvert: Array<HookFunction | AsyncHookFunction>;\r\n perRow: Array<PerRowHookFunction | AsyncPerRowHookFunction>;\r\n };\r\n\r\n constructor(options?: TransformHooksOptions) {\r\n this.hooks = {\r\n beforeConvert: options?.hooks?.beforeConvert || [],\r\n afterConvert: options?.hooks?.afterConvert || [],\r\n perRow: options?.hooks?.perRow || []\r\n };\r\n }\r\n\r\n /**\r\n * Регистрирует хук beforeConvert\r\n * @param hook - Функция хука\r\n * @returns this для цепочки вызовов\r\n */\r\n beforeConvert(hook: HookFunction | AsyncHookFunction): this {\r\n if (typeof hook !== 'function') {\r\n throw new ValidationError('beforeConvert hook must be a function');\r\n }\r\n this.hooks.beforeConvert.push(hook);\r\n return this;\r\n }\r\n\r\n /**\r\n * Регистрирует хук afterConvert\r\n * @param hook - Функция хука\r\n * @returns this для цепочки вызовов\r\n */\r\n afterConvert(hook: HookFunction | AsyncHookFunction): this {\r\n if (typeof hook !== 'function') {\r\n throw new ValidationError('afterConvert hook must be a function');\r\n }\r\n this.hooks.afterConvert.push(hook);\r\n return this;\r\n }\r\n\r\n /**\r\n * Регистрирует per-row хук\r\n * @param hook - Функция хука\r\n * @returns this для цепочки вызовов\r\n */\r\n perRow(hook: PerRowHookFunction | AsyncPerRowHookFunction): this {\r\n if (typeof hook !== 'function') {\r\n throw new ValidationError('perRow hook must be a function');\r\n }\r\n this.hooks.perRow.push(hook);\r\n return this;\r\n }\r\n\r\n /**\r\n * Применяет beforeConvert хуки\r\n * @param data - Входные данные\r\n * @param context - Контекст выполнения\r\n * @returns Трансформированные данные\r\n */\r\n applyBeforeConvert<T = any, R = any>(data: T, context: HookContext = {}): R {\r\n let result: any = data;\r\n for (const hook of this.hooks.beforeConvert) {\r\n result = hook(result, context);\r\n }\r\n return result as R;\r\n }\r\n\r\n /**\r\n * Применяет beforeConvert хуки асинхронно\r\n * @param data - Входные данные\r\n * @param context - Контекст выполнения\r\n * @returns Promise с трансформированными данными\r\n */\r\n async applyBeforeConvertAsync<T = any, R = any>(data: T, context: HookContext = {}): Promise<R> {\r\n let result: any = data;\r\n for (const hook of this.hooks.beforeConvert) {\r\n if (this.isAsyncFunction(hook)) {\r\n result = await (hook as AsyncHookFunction)(result, context);\r\n } else {\r\n result = (hook as HookFunction)(result, context);\r\n }\r\n }\r\n return result as R;\r\n }\r\n\r\n /**\r\n * Применяет afterConvert хуки\r\n * @param data - Выходные данные\r\n * @param context - Контекст выполнения\r\n * @returns Трансформированные данные\r\n */\r\n applyAfterConvert<T = any, R = any>(data: T, context: HookContext = {}): R {\r\n let result: any = data;\r\n for (const hook of this.hooks.afterConvert) {\r\n result = hook(result, context);\r\n }\r\n return result as R;\r\n }\r\n\r\n /**\r\n * Применяет afterConvert хуки асинхронно\r\n * @param data - Выходные данные\r\n * @param context - Контекст выполнения\r\n * @returns Promise с трансформированными данными\r\n */\r\n async applyAfterConvertAsync<T = any, R = any>(data: T, context: HookContext = {}): Promise<R> {\r\n let result: any = data;\r\n for (const hook of this.hooks.afterConvert) {\r\n if (this.isAsyncFunction(hook)) {\r\n result = await (hook as AsyncHookFunction)(result, context);\r\n } else {\r\n result = (hook as HookFunction)(result, context);\r\n }\r\n }\r\n return result as R;\r\n }\r\n\r\n /**\r\n * Применяет per-row хуки\r\n * @param row - Строка данных\r\n * @param index - Индекс строки\r\n * @param context - Контекст выполнения\r\n * @returns Трансформированная строка\r\n */\r\n applyPerRow<T = any, R = any>(row: T, index: number, context: HookContext = {}): R {\r\n let result: any = row;\r\n for (const hook of this.hooks.perRow) {\r\n result = hook(result, index, context);\r\n }\r\n return result as R;\r\n }\r\n\r\n /**\r\n * Применяет per-row хуки асинхронно\r\n * @param row - Строка данных\r\n * @param index - Индекс строки\r\n * @param context - Контекст выполнения\r\n * @returns Promise с трансформированной строкой\r\n */\r\n async applyPerRowAsync<T = any, R = any>(row: T, index: number, context: HookContext = {}): Promise<R> {\r\n let result: any = row;\r\n for (const hook of this.hooks.perRow) {\r\n if (this.isAsyncFunction(hook)) {\r\n result = await (hook as AsyncPerRowHookFunction)(result, index, context);\r\n } else {\r\n result = (hook as PerRowHookFunction)(result, index, context);\r\n }\r\n }\r\n return result as R;\r\n }\r\n\r\n /**\r\n * Применяет все хуки к массиву данных\r\n * @param data - Массив данных\r\n * @param context - Контекст выполнения\r\n * @returns Трансформированный массив\r\n */\r\n applyAll<T = any, R = any>(data: T[], context: HookContext = {}): R[] {\r\n if (!Array.isArray(data)) {\r\n throw new ValidationError('Data must be an array for applyAll');\r\n }\r\n\r\n // Применяем beforeConvert хуки\r\n let processedData: any[] = this.applyBeforeConvert(data, context);\r\n\r\n // Применяем per-row хуки к каждой строке\r\n if (this.hooks.perRow.length > 0) {\r\n processedData = processedData.map((row: any, index: number) => \r\n this.applyPerRow(row, index, context)\r\n );\r\n }\r\n\r\n // Применяем afterConvert хуки\r\n return this.applyAfterConvert(processedData, context) as R[];\r\n }\r\n\r\n /**\r\n * Применяет все хуки к массиву данных асинхронно\r\n * @param data - Массив данных\r\n * @param context - Контекст выполнения\r\n * @returns Promise с трансформированным массивом\r\n */\r\n async applyAllAsync<T = any, R = any>(data: T[], context: HookContext = {}): Promise<R[]> {\r\n if (!Array.isArray(data)) {\r\n throw new ValidationError('Data must be an array for applyAll');\r\n }\r\n\r\n // Применяем beforeConvert хуки асинхронно\r\n let processedData = await this.applyBeforeConvertAsync(data, context);\r\n\r\n // Применяем per-row хуки асинхронно к каждой строке\r\n if (this.hooks.perRow.length > 0) {\r\n const processedRows: any[] = [];\r\n for (let i = 0; i < processedData.length; i++) {\r\n const processedRow = await this.applyPerRowAsync(processedData[i], i, context);\r\n processedRows.push(processedRow);\r\n }\r\n processedData = processedRows;\r\n }\r\n\r\n // Применяем afterConvert хуки асинхронно\r\n return await this.applyAfterConvertAsync(processedData, context) as R[];\r\n }\r\n\r\n /**\r\n * Создает копию системы хуков\r\n * @returns Новая копия\r\n */\r\n clone(): TransformHooks {\r\n const cloned = new TransformHooks();\r\n cloned.hooks = {\r\n beforeConvert: [...this.hooks.beforeConvert],\r\n afterConvert: [...this.hooks.afterConvert],\r\n perRow: [...this.hooks.perRow]\r\n };\r\n return cloned;\r\n }\r\n\r\n /**\r\n * Очищает все хуки\r\n */\r\n clear(): void {\r\n this.hooks = {\r\n beforeConvert: [],\r\n afterConvert: [],\r\n perRow: []\r\n };\r\n }\r\n\r\n /**\r\n * Возвращает статистику по хукам\r\n * @returns Статистика\r\n */\r\n getStats(): { beforeConvert: number; afterConvert: number; perRow: number; total: number } {\r\n return {\r\n beforeConvert: this.hooks.beforeConvert.length,\r\n afterConvert: this.hooks.afterConvert.length,\r\n perRow: this.hooks.perRow.length,\r\n total: this.hooks.beforeConvert.length + \r\n this.hooks.afterConvert.length + \r\n this.hooks.perRow.length\r\n };\r\n }\r\n\r\n /**\r\n * Проверяет, является ли функция асинхронной\r\n * @private\r\n */\r\n private isAsyncFunction(fn: any): boolean {\r\n return fn.constructor.name === 'AsyncFunction' || \r\n (typeof fn === 'function' && fn.constructor === (async () => {}).constructor);\r\n }\r\n}\r\n\r\n/**\r\n * Предопределенные хуки\r\n */\r\nexport const predefinedHooks = {\r\n /**\r\n * Хук для фильтрации данных\r\n * @param predicate - Функция-предикат\r\n * @returns Хук фильтрации\r\n */\r\n filter<T>(predicate: (item: T, index: number) => boolean): HookFunction<T[], T[]> {\r\n return (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n return data.filter(predicate);\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Асинхронный хук для фильтрации данных\r\n * @param predicate - Асинхронная функция-предикат\r\n * @returns Асинхронный хук фильтрации\r\n */\r\n filterAsync<T>(predicate: (item: T, index: number) => Promise<boolean>): AsyncHookFunction<T[], T[]> {\r\n return async (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n const filtered: T[] = [];\r\n for (let i = 0; i < data.length; i++) {\r\n if (await predicate(data[i], i)) {\r\n filtered.push(data[i]);\r\n }\r\n }\r\n return filtered;\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Хук для маппинга данных\r\n * @param mapper - Функция-маппер\r\n * @returns Хук маппинга\r\n */\r\n map<T, R>(mapper: (item: T, index: number) => R): HookFunction<T[], R[]> {\r\n return (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n return data.map(mapper);\r\n }\r\n return data as any;\r\n };\r\n },\r\n\r\n /**\r\n * Асинхронный хук для маппинга данных\r\n * @param mapper - Асинхронная функция-маппер\r\n * @returns Асинхронный хук маппинга\r\n */\r\n mapAsync<T, R>(mapper: (item: T, index: number) => Promise<R>): AsyncHookFunction<T[], R[]> {\r\n return async (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n const mapped: R[] = [];\r\n for (let i = 0; i < data.length; i++) {\r\n mapped.push(await mapper(data[i], i));\r\n }\r\n return mapped;\r\n }\r\n return data as any;\r\n };\r\n },\r\n\r\n /**\r\n * Хук для сортировки данных\r\n * @param compareFn - Функция сравнения\r\n * @returns Хук сортировки\r\n */\r\n sort<T>(compareFn?: (a: T, b: T) => number): HookFunction<T[], T[]> {\r\n return (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n return [...data].sort(compareFn);\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Хук для ограничения количества записей\r\n * @param limit - Максимальное количество записей\r\n * @returns Хук ограничения\r\n */\r\n limit<T>(limit: number): HookFunction<T[], T[]> {\r\n return (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n return data.slice(0, limit);\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Хук для добавления метаданных\r\n * @param metadata - Метаданные для добавления\r\n * @returns Хук добавления метаданных\r\n */\r\n addMetadata<T extends Record<string, any>>(metadata: Record<string, any>): HookFunction<T[], Array<T & { _metadata: any }>> {\r\n return (data: T[], context?: HookContext) => {\r\n if (Array.isArray(data)) {\r\n return data.map(item => ({\r\n ...item,\r\n _metadata: {\r\n ...metadata,\r\n timestamp: new Date().toISOString(),\r\n context\r\n }\r\n })) as Array<T & { _metadata: any }>;\r\n }\r\n return data as any;\r\n };\r\n },\r\n\r\n /**\r\n * Хук для преобразования ключей\r\n * @param keyTransformer - Функция преобразования ключей\r\n * @returns Хук преобразования ключей\r\n */\r\n transformKeys<T extends Record<string, any>>(keyTransformer: (key: string) => string): HookFunction<T[], Array<Record<string, any>>> {\r\n return (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n return data.map(item => {\r\n const transformed: Record<string, any> = {};\r\n for (const [key, value] of Object.entries(item)) {\r\n transformed[keyTransformer(key)] = value;\r\n }\r\n return transformed;\r\n });\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Хук для преобразования значений\r\n * @param valueTransformer - Функция преобразования значений\r\n * @returns Хук преобразования значений\r\n */\r\n transformValues<T extends Record<string, any>>(valueTransformer: (value: any, key: string) => any): HookFunction<T[], Array<Record<string, any>>> {\r\n return (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n return data.map(item => {\r\n const transformed: Record<string, any> = {};\r\n for (const [key, value] of Object.entries(item)) {\r\n transformed[key] = valueTransformer(value, key);\r\n }\r\n return transformed;\r\n });\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Хук для валидации данных\r\n * @param validator - Функция валидации\r\n * @param onError - Обработчик ошибки\r\n * @returns Хук валидации\r\n */\r\n validate<T>(validator: (item: T, index: number) => boolean, onError: (errors: any[] | string, details?: any[]) => void = console.error): HookFunction<T[], T[]> {\n return (data: T[]) => {\n if (Array.isArray(data)) {\n const validData: T[] = [];\n const errors: any[] = [];\n\r\n data.forEach((item, index) => {\r\n try {\r\n const isValid = validator(item, index);\r\n if (isValid) {\r\n validData.push(item);\r\n } else {\r\n errors.push({ index, item, reason: 'Validation failed' });\r\n }\r\n } catch (error: any) {\r\n errors.push({ index, item, error: error.message });\r\n }\r\n });\r\n\r\n if (errors.length > 0) {\n if (onError.length >= 2) {\n onError('Validation errors', errors);\n } else {\n onError(errors);\n }\n }\n\r\n return validData;\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Асинхронный хук для валидации данных\r\n * @param validator - Асинхронная функция валидации\r\n * @param onError - Обработчик ошибки\r\n * @returns Асинхронный хук валидации\r\n */\r\n validateAsync<T>(validator: (item: T, index: number) => Promise<boolean>, onError: (errors: any[] | string, details?: any[]) => void = console.error): AsyncHookFunction<T[], T[]> {\n return async (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n const validData: T[] = [];\r\n const errors: any[] = [];\r\n\r\n for (let i = 0; i < data.length; i++) {\r\n try {\r\n const isValid = await validator(data[i], i);\r\n if (isValid) {\r\n validData.push(data[i]);\r\n } else {\r\n errors.push({ index: i, item: data[i], reason: 'Validation failed' });\r\n }\r\n } catch (error: any) {\r\n errors.push({ index: i, item: data[i], error: error.message });\r\n }\r\n }\r\n\r\n if (errors.length > 0) {\n if (onError.length >= 2) {\n onError('Validation errors', errors);\n } else {\n onError(errors);\n }\n }\n\r\n return validData;\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Хук для дедупликации данных\r\n * @param keySelector - Функция выбора ключа\r\n * @returns Хук дедупликации\r\n */\r\n deduplicate<T>(keySelector: (item: T) => string = JSON.stringify): HookFunction<T[], T[]> {\r\n return (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n const seen = new Set<string>();\r\n return data.filter(item => {\r\n const key = keySelector(item);\r\n if (seen.has(key)) {\r\n return false;\r\n }\r\n seen.add(key);\r\n return true;\r\n });\r\n }\r\n return data;\r\n };\r\n },\r\n\r\n /**\r\n * Асинхронный хук для дедупликации данных\r\n * @param keySelector - Асинхронная функция выбора ключа\r\n * @returns Асинхронный хук дедупликации\r\n */\r\n deduplicateAsync<T>(keySelector: (item: T) => Promise<string> = async (item) => JSON.stringify(item)): AsyncHookFunction<T[], T[]> {\r\n return async (data: T[]) => {\r\n if (Array.isArray(data)) {\r\n const seen = new Set<string>();\r\n const filtered: T[] = [];\r\n \r\n for (const item of data) {\r\n const key = await keySelector(item);\r\n if (!seen.has(key)) {\r\n seen.add(key);\r\n filtered.push(item);\r\n }\r\n }\r\n \r\n return filtered;\r\n }\r\n return data;\r\n };\r\n }\r\n};\r\n"]}
@@ -0,0 +1,262 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class FastPathEngine {
4
+ constructor() {
5
+ this.compilers = new Map();
6
+ this.stats = {
7
+ simpleParserCount: 0,
8
+ quoteAwareParserCount: 0,
9
+ standardParserCount: 0,
10
+ cacheHits: 0,
11
+ cacheMisses: 0
12
+ };
13
+ }
14
+ analyzeStructure(sample, options = {}) {
15
+ const delimiter = options.delimiter || this._detectDelimiter(sample);
16
+ const lines = sample.split('\n').slice(0, 10);
17
+ let hasQuotes = false;
18
+ let hasNewlinesInFields = false;
19
+ let hasEscapedQuotes = false;
20
+ let maxFields = 0;
21
+ let totalFields = 0;
22
+ for (const line of lines) {
23
+ if (line.includes('"')) {
24
+ hasQuotes = true;
25
+ if (line.includes('""')) {
26
+ hasEscapedQuotes = true;
27
+ }
28
+ }
29
+ const quoteCount = (line.match(/"/g) || []).length;
30
+ if (quoteCount % 2 !== 0) {
31
+ hasNewlinesInFields = true;
32
+ }
33
+ const fieldCount = line.split(delimiter).length;
34
+ totalFields += fieldCount;
35
+ if (fieldCount > maxFields) {
36
+ maxFields = fieldCount;
37
+ }
38
+ }
39
+ const avgFieldsPerLine = totalFields / lines.length;
40
+ const fieldConsistency = maxFields === avgFieldsPerLine;
41
+ return {
42
+ delimiter,
43
+ hasQuotes,
44
+ hasEscapedQuotes,
45
+ hasNewlinesInFields,
46
+ fieldConsistency,
47
+ avgFieldsPerLine,
48
+ maxFields,
49
+ recommendedEngine: this._selectEngine(hasQuotes, hasNewlinesInFields, fieldConsistency)
50
+ };
51
+ }
52
+ _detectDelimiter(sample) {
53
+ const candidates = [',', ';', '\t', '|'];
54
+ const firstLine = sample.split('\n')[0];
55
+ let bestDelimiter = ',';
56
+ let bestScore = 0;
57
+ for (const delimiter of candidates) {
58
+ const fields = firstLine.split(delimiter);
59
+ const score = fields.length;
60
+ const avgLength = fields.reduce((sum, field) => sum + field.length, 0) / fields.length;
61
+ const variance = fields.reduce((sum, field) => sum + Math.pow(field.length - avgLength, 2), 0) / fields.length;
62
+ const finalScore = score / (variance + 1);
63
+ if (finalScore > bestScore) {
64
+ bestScore = finalScore;
65
+ bestDelimiter = delimiter;
66
+ }
67
+ }
68
+ return bestDelimiter;
69
+ }
70
+ _selectEngine(hasQuotes, hasNewlinesInFields, fieldConsistency) {
71
+ if (!hasQuotes && !hasNewlinesInFields && fieldConsistency) {
72
+ return 'SIMPLE';
73
+ }
74
+ if (hasQuotes && !hasNewlinesInFields) {
75
+ return 'QUOTE_AWARE';
76
+ }
77
+ return 'STANDARD';
78
+ }
79
+ compileParser(structure) {
80
+ const cacheKey = JSON.stringify(structure);
81
+ if (this.compilers.has(cacheKey)) {
82
+ this.stats.cacheHits++;
83
+ return this.compilers.get(cacheKey);
84
+ }
85
+ this.stats.cacheMisses++;
86
+ let parser;
87
+ switch (structure.recommendedEngine) {
88
+ case 'SIMPLE':
89
+ parser = this._createSimpleParser(structure);
90
+ this.stats.simpleParserCount++;
91
+ break;
92
+ case 'QUOTE_AWARE':
93
+ parser = this._createQuoteAwareParser(structure);
94
+ this.stats.quoteAwareParserCount++;
95
+ break;
96
+ default:
97
+ parser = this._createStandardParser(structure);
98
+ this.stats.standardParserCount++;
99
+ }
100
+ this.compilers.set(cacheKey, parser);
101
+ return parser;
102
+ }
103
+ _createSimpleParser(structure) {
104
+ const { delimiter } = structure;
105
+ return (csv) => {
106
+ const rows = [];
107
+ const lines = csv.split('\n');
108
+ for (const line of lines) {
109
+ if (line.trim() === '') {
110
+ continue;
111
+ }
112
+ const fields = line.split(delimiter).map(field => field.trim());
113
+ if (fields.length > 0 && fields.some(field => field !== '')) {
114
+ rows.push(fields);
115
+ }
116
+ }
117
+ return rows;
118
+ };
119
+ }
120
+ _createQuoteAwareParser(structure) {
121
+ const { delimiter, hasEscapedQuotes } = structure;
122
+ return (csv) => {
123
+ const rows = [];
124
+ let currentRow = [];
125
+ let currentField = '';
126
+ let insideQuotes = false;
127
+ let i = 0;
128
+ while (i < csv.length) {
129
+ const char = csv[i];
130
+ const nextChar = csv[i + 1];
131
+ if (char === '"') {
132
+ if (insideQuotes) {
133
+ if (nextChar === '"' && hasEscapedQuotes) {
134
+ currentField += '"';
135
+ i += 2;
136
+ }
137
+ else {
138
+ insideQuotes = false;
139
+ i++;
140
+ }
141
+ }
142
+ else {
143
+ insideQuotes = true;
144
+ i++;
145
+ }
146
+ }
147
+ else if (char === delimiter && !insideQuotes) {
148
+ currentRow.push(currentField);
149
+ currentField = '';
150
+ i++;
151
+ }
152
+ else if ((char === '\n' || (char === '\r' && nextChar === '\n')) && !insideQuotes) {
153
+ currentRow.push(currentField);
154
+ if (currentRow.length > 0 && currentRow.some(field => field !== '')) {
155
+ rows.push(currentRow);
156
+ }
157
+ currentRow = [];
158
+ currentField = '';
159
+ i += (char === '\r' && nextChar === '\n') ? 2 : 1;
160
+ }
161
+ else {
162
+ currentField += char;
163
+ i++;
164
+ }
165
+ }
166
+ if (currentField !== '' || currentRow.length > 0) {
167
+ currentRow.push(currentField);
168
+ if (currentRow.length > 0 && currentRow.some(field => field !== '')) {
169
+ rows.push(currentRow);
170
+ }
171
+ }
172
+ return rows;
173
+ };
174
+ }
175
+ _createStandardParser(structure) {
176
+ const { delimiter } = structure;
177
+ return (csv) => {
178
+ const rows = [];
179
+ const lines = csv.split('\n');
180
+ let insideQuotes = false;
181
+ let currentLine = '';
182
+ for (const line of lines) {
183
+ const quoteCount = (line.match(/"/g) || []).length;
184
+ if (insideQuotes) {
185
+ currentLine += '\n' + line;
186
+ if (quoteCount % 2 !== 0) {
187
+ insideQuotes = false;
188
+ rows.push(this._parseLineWithQuotes(currentLine, delimiter));
189
+ currentLine = '';
190
+ }
191
+ }
192
+ else {
193
+ if (quoteCount % 2 !== 0) {
194
+ insideQuotes = true;
195
+ currentLine = line;
196
+ }
197
+ else {
198
+ rows.push(this._parseLineWithQuotes(line, delimiter));
199
+ }
200
+ }
201
+ }
202
+ return rows;
203
+ };
204
+ }
205
+ _parseLineWithQuotes(line, delimiter) {
206
+ const fields = [];
207
+ let currentField = '';
208
+ let insideQuotes = false;
209
+ let i = 0;
210
+ while (i < line.length) {
211
+ const char = line[i];
212
+ const nextChar = line[i + 1];
213
+ if (char === '"') {
214
+ if (insideQuotes && nextChar === '"') {
215
+ currentField += '"';
216
+ i += 2;
217
+ }
218
+ else {
219
+ insideQuotes = !insideQuotes;
220
+ i++;
221
+ }
222
+ }
223
+ else if (char === delimiter && !insideQuotes) {
224
+ fields.push(currentField);
225
+ currentField = '';
226
+ i++;
227
+ }
228
+ else {
229
+ currentField += char;
230
+ i++;
231
+ }
232
+ }
233
+ fields.push(currentField);
234
+ return fields;
235
+ }
236
+ parse(csv, options = {}) {
237
+ const sampleSize = Math.min(1000, csv.length);
238
+ const sample = csv.substring(0, sampleSize);
239
+ const structure = this.analyzeStructure(sample, options);
240
+ const parser = this.compileParser(structure);
241
+ return parser(csv);
242
+ }
243
+ getStats() {
244
+ return {
245
+ ...this.stats,
246
+ totalParsers: this.compilers.size,
247
+ hitRate: this.stats.cacheHits / (this.stats.cacheHits + this.stats.cacheMisses) || 0
248
+ };
249
+ }
250
+ reset() {
251
+ this.compilers.clear();
252
+ this.stats = {
253
+ simpleParserCount: 0,
254
+ quoteAwareParserCount: 0,
255
+ standardParserCount: 0,
256
+ cacheHits: 0,
257
+ cacheMisses: 0
258
+ };
259
+ }
260
+ }
261
+ exports.default = FastPathEngine;
262
+ //# sourceMappingURL=fast-path-engine-new.js.map