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
@@ -1,406 +0,0 @@
1
- /**
2
- * Fastify plugin для JTCSV
3
- * Плагин для автоматической конвертации CSV/JSON в Fastify приложениях
4
- *
5
- * @version 1.0.0
6
- * @date 2026-01-23
7
- */
8
-
9
- const fp = require('fastify-plugin');
10
- const { csvToJson, jsonToCsv } = require('../../index.js');
11
-
12
- /**
13
- * Fastify plugin для JTCSV
14
- *
15
- * @param {Object} fastify - Fastify instance
16
- * @param {Object} options - Опции плагина
17
- * @param {Function} next - Callback
18
- *
19
- * @example
20
- * // Базовое использование
21
- * const fastify = require('fastify')();
22
- * await fastify.register(require('@jtcsv/fastify'), {
23
- * prefix: '/api/convert'
24
- * });
25
- *
26
- * @example
27
- * // С кастомными опциями
28
- * await fastify.register(require('@jtcsv/fastify'), {
29
- * prefix: '/api',
30
- * enableFastPath: true,
31
- * delimiter: ';'
32
- * });
33
- */
34
- async function jtcsvFastifyPlugin(fastify, options = {}) {
35
- const {
36
- prefix = '/convert',
37
- delimiter = ',',
38
- enableFastPath = true,
39
- preventCsvInjection = true,
40
- rfc4180Compliant = true
41
- } = options;
42
-
43
- // Health check endpoint
44
- fastify.get(`${prefix}/health`, async () => {
45
- return {
46
- service: 'jtcsv-fastify-plugin',
47
- status: 'healthy',
48
- version: '1.0.0',
49
- timestamp: new Date().toISOString(),
50
- features: {
51
- csvToJson: true,
52
- jsonToCsv: true,
53
- fastPathEngine: enableFastPath,
54
- csvInjectionProtection: preventCsvInjection,
55
- streaming: true,
56
- ndjson: true
57
- }
58
- };
59
- });
60
-
61
- // CSV to JSON endpoint
62
- fastify.post(`${prefix}/csv-to-json`, {
63
- schema: {
64
- body: {
65
- type: 'object',
66
- required: ['csv'],
67
- properties: {
68
- csv: { type: 'string' },
69
- delimiter: { type: 'string', default: delimiter },
70
- parseNumbers: { type: 'boolean', default: true },
71
- parseBooleans: { type: 'boolean', default: true },
72
- useFastPath: { type: 'boolean', default: enableFastPath }
73
- }
74
- },
75
- response: {
76
- 200: {
77
- type: 'object',
78
- properties: {
79
- success: { type: 'boolean' },
80
- data: { type: 'array' },
81
- stats: {
82
- type: 'object',
83
- properties: {
84
- rows: { type: 'number' },
85
- processingTime: { type: 'number' }
86
- }
87
- }
88
- }
89
- }
90
- }
91
- }
92
- }, async (request, reply) => {
93
- const startTime = Date.now();
94
- const {
95
- csv,
96
- delimiter: reqDelimiter = delimiter,
97
- parseNumbers = true,
98
- parseBooleans = true,
99
- useFastPath = enableFastPath
100
- } = request.body;
101
-
102
- try {
103
- const json = await csvToJson(csv, {
104
- delimiter: reqDelimiter,
105
- parseNumbers,
106
- parseBooleans,
107
- useFastPath,
108
- preventCsvInjection,
109
- rfc4180Compliant
110
- });
111
-
112
- return {
113
- success: true,
114
- data: json,
115
- stats: {
116
- rows: json.length,
117
- processingTime: Date.now() - startTime
118
- }
119
- };
120
- } catch (error) {
121
- reply.code(400);
122
- return {
123
- success: false,
124
- error: error.message,
125
- code: 'CSV_CONVERSION_ERROR'
126
- };
127
- }
128
- });
129
-
130
- // JSON to CSV endpoint
131
- fastify.post(`${prefix}/json-to-csv`, {
132
- schema: {
133
- body: {
134
- type: 'object',
135
- required: ['json'],
136
- properties: {
137
- json: { type: 'array' },
138
- delimiter: { type: 'string', default: delimiter },
139
- includeHeaders: { type: 'boolean', default: true },
140
- useFastPath: { type: 'boolean', default: enableFastPath }
141
- }
142
- },
143
- response: {
144
- 200: {
145
- type: 'object',
146
- properties: {
147
- success: { type: 'boolean' },
148
- data: { type: 'string' },
149
- stats: {
150
- type: 'object',
151
- properties: {
152
- size: { type: 'number' },
153
- processingTime: { type: 'number' }
154
- }
155
- }
156
- }
157
- }
158
- }
159
- }
160
- }, async (request, reply) => {
161
- const startTime = Date.now();
162
- const {
163
- json,
164
- delimiter: reqDelimiter = delimiter,
165
- includeHeaders = true,
166
- useFastPath = enableFastPath
167
- } = request.body;
168
-
169
- try {
170
- const csv = await jsonToCsv(json, {
171
- delimiter: reqDelimiter,
172
- includeHeaders,
173
- useFastPath,
174
- preventCsvInjection,
175
- rfc4180Compliant
176
- });
177
-
178
- return {
179
- success: true,
180
- data: csv,
181
- stats: {
182
- size: Buffer.byteLength(csv),
183
- processingTime: Date.now() - startTime
184
- }
185
- };
186
- } catch (error) {
187
- reply.code(400);
188
- return {
189
- success: false,
190
- error: error.message,
191
- code: 'JSON_CONVERSION_ERROR'
192
- };
193
- }
194
- });
195
-
196
- // Универсальный endpoint для автоматической конвертации
197
- fastify.post(`${prefix}/auto`, {
198
- schema: {
199
- body: {
200
- oneOf: [
201
- { type: 'string' }, // CSV data
202
- { type: 'array' }, // JSON array
203
- { type: 'object' } // JSON object
204
- ]
205
- },
206
- headers: {
207
- type: 'object',
208
- properties: {
209
- 'content-type': {
210
- type: 'string',
211
- enum: ['application/json', 'text/csv', 'text/plain']
212
- },
213
- 'accept': {
214
- type: 'string',
215
- enum: ['application/json', 'text/csv']
216
- }
217
- }
218
- },
219
- querystring: {
220
- type: 'object',
221
- properties: {
222
- format: { type: 'string', enum: ['json', 'csv'] },
223
- delimiter: { type: 'string' }
224
- }
225
- }
226
- }
227
- }, async (request, reply) => {
228
- const startTime = Date.now();
229
- const contentType = request.headers['content-type'] || '';
230
- const acceptHeader = request.headers['accept'] || 'application/json';
231
- const { format, delimiter: queryDelimiter } = request.query;
232
-
233
- const reqDelimiter = queryDelimiter || delimiter;
234
-
235
- try {
236
- let inputFormat = 'unknown';
237
- let outputFormat = format || (acceptHeader.includes('text/csv') ? 'csv' : 'json');
238
-
239
- // Определяем формат входных данных
240
- if (contentType.includes('application/json') || Array.isArray(request.body)) {
241
- inputFormat = 'json';
242
- } else if (contentType.includes('text/csv') ||
243
- contentType.includes('text/plain') ||
244
- (typeof request.body === 'string' && request.body.includes(','))) {
245
- inputFormat = 'csv';
246
- }
247
-
248
- if (inputFormat === 'unknown') {
249
- reply.code(400);
250
- return {
251
- success: false,
252
- error: 'Unable to determine input format',
253
- code: 'UNKNOWN_FORMAT'
254
- };
255
- }
256
-
257
- let result;
258
- let stats = {
259
- inputSize: 0,
260
- outputSize: 0,
261
- processingTime: 0,
262
- conversion: `${inputFormat}→${outputFormat}`
263
- };
264
-
265
- const conversionOptions = {
266
- delimiter: reqDelimiter,
267
- useFastPath: enableFastPath,
268
- preventCsvInjection,
269
- rfc4180Compliant
270
- };
271
-
272
- if (inputFormat === 'json' && outputFormat === 'csv') {
273
- const jsonData = Array.isArray(request.body) ? request.body : [request.body];
274
- stats.inputSize = Buffer.byteLength(JSON.stringify(jsonData));
275
-
276
- result = await jsonToCsv(jsonData, {
277
- ...conversionOptions,
278
- includeHeaders: true
279
- });
280
- stats.outputSize = Buffer.byteLength(result);
281
-
282
- reply.header('Content-Type', 'text/csv; charset=utf-8');
283
-
284
- } else if (inputFormat === 'csv' && outputFormat === 'json') {
285
- const csvData = typeof request.body === 'string' ? request.body : String(request.body);
286
- stats.inputSize = Buffer.byteLength(csvData);
287
-
288
- result = await csvToJson(csvData, {
289
- ...conversionOptions,
290
- parseNumbers: true,
291
- parseBooleans: true
292
- });
293
- stats.outputSize = Buffer.byteLength(JSON.stringify(result));
294
-
295
- reply.header('Content-Type', 'application/json; charset=utf-8');
296
-
297
- } else {
298
- // Нет необходимости в конвертации
299
- result = request.body;
300
- stats.conversion = 'none';
301
- stats.inputSize = Buffer.byteLength(JSON.stringify(result));
302
- stats.outputSize = stats.inputSize;
303
- }
304
-
305
- stats.processingTime = Date.now() - startTime;
306
-
307
- return {
308
- success: true,
309
- data: result,
310
- format: outputFormat,
311
- inputFormat,
312
- stats
313
- };
314
-
315
- } catch (error) {
316
- reply.code(400);
317
- return {
318
- success: false,
319
- error: error.message,
320
- code: 'CONVERSION_ERROR',
321
- details: process.env.NODE_ENV === 'development' ? error.stack : undefined
322
- };
323
- }
324
- });
325
-
326
- // Streaming endpoint для больших файлов
327
- fastify.post(`${prefix}/stream`, {
328
- schema: {
329
- body: {
330
- type: 'object',
331
- required: ['direction'],
332
- properties: {
333
- direction: {
334
- type: 'string',
335
- enum: ['csv-to-json', 'json-to-csv']
336
- },
337
- delimiter: { type: 'string', default: delimiter }
338
- }
339
- }
340
- }
341
- }, async (request, reply) => {
342
- const { direction, delimiter: reqDelimiter = delimiter } = request.body;
343
-
344
- if (direction === 'csv-to-json') {
345
- reply.header('Content-Type', 'application/x-ndjson');
346
- reply.header('Transfer-Encoding', 'chunked');
347
-
348
- // Здесь будет реализация streaming
349
- // Пока возвращаем заглушку
350
- reply.send(JSON.stringify({
351
- success: false,
352
- error: 'Streaming endpoint not implemented yet',
353
- code: 'NOT_IMPLEMENTED'
354
- }));
355
-
356
- } else if (direction === 'json-to-csv') {
357
- reply.header('Content-Type', 'text/csv');
358
- reply.header('Transfer-Encoding', 'chunked');
359
-
360
- // Здесь будет реализация streaming
361
- reply.send('Streaming endpoint not implemented yet\n');
362
- }
363
- });
364
-
365
- // Декоратор для прямого доступа к функциям конвертации
366
- fastify.decorate('jtcsv', {
367
- csvToJson: async (csv, options = {}) => {
368
- return csvToJson(csv, {
369
- delimiter,
370
- useFastPath: enableFastPath,
371
- preventCsvInjection,
372
- rfc4180Compliant,
373
- ...options
374
- });
375
- },
376
-
377
- jsonToCsv: async (json, options = {}) => {
378
- return jsonToCsv(json, {
379
- delimiter,
380
- useFastPath: enableFastPath,
381
- preventCsvInjection,
382
- rfc4180Compliant,
383
- ...options
384
- });
385
- },
386
-
387
- health: () => ({
388
- service: 'jtcsv-fastify-plugin',
389
- status: 'healthy',
390
- version: '1.0.0'
391
- })
392
- });
393
-
394
- console.log(`✅ JTCSV Fastify plugin зарегистрирован с префиксом: ${prefix}`);
395
- }
396
-
397
- // Экспортируем как Fastify plugin
398
- module.exports = fp(jtcsvFastifyPlugin, {
399
- fastify: '4.x',
400
- name: '@jtcsv/fastify'
401
- });
402
-
403
- // Экспортируем также как обычную функцию
404
- module.exports.jtcsvFastifyPlugin = jtcsvFastifyPlugin;
405
-
406
-
@@ -1,55 +0,0 @@
1
- {
2
- "name": "@jtcsv/fastify",
3
- "version": "1.0.0",
4
- "description": "Fastify plugin для автоматической конвертации CSV/JSON",
5
- "main": "index.js",
6
- "types": "index.d.ts",
7
- "scripts": {
8
- "test": "jest",
9
- "lint": "eslint index.js",
10
- "example": "node example.js"
11
- },
12
- "keywords": [
13
- "fastify",
14
- "plugin",
15
- "csv",
16
- "json",
17
- "converter",
18
- "jtcsv",
19
- "api",
20
- "rest",
21
- "http",
22
- "streaming"
23
- ],
24
- "author": "Ruslan Fomenko",
25
- "license": "MIT",
26
- "repository": {
27
- "type": "git",
28
- "url": "git+https://github.com/Linol-Hamelton/jtcsv.git",
29
- "directory": "plugins/fastify-plugin"
30
- },
31
- "bugs": {
32
- "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
33
- },
34
- "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/fastify-plugin#readme",
35
- "peerDependencies": {
36
- "fastify": "^4.0.0",
37
- "fastify-plugin": "^4.0.0",
38
- "jtcsv": "^2.1.0"
39
- },
40
- "devDependencies": {
41
- "fastify": "^4.0.0",
42
- "fastify-plugin": "^4.0.0",
43
- "jest": "^29.0.0",
44
- "eslint": "^8.57.0",
45
- "supertest": "^6.3.0"
46
- },
47
- "files": [
48
- "index.js",
49
- "index.d.ts",
50
- "README.md",
51
- "example.js"
52
- ]
53
- }
54
-
55
-
@@ -1,28 +0,0 @@
1
- # @jtcsv/hono
2
-
3
- Minimal helpers for Hono routes.
4
-
5
- ## Install
6
- ```bash
7
- npm install @jtcsv/hono jtcsv
8
- ```
9
-
10
- ## Usage
11
- ```javascript
12
- import { Hono } from 'hono';
13
- import { csvMiddleware, createCsvResponse } from '@jtcsv/hono';
14
-
15
- const app = new Hono();
16
-
17
- app.use('/upload', csvMiddleware());
18
- app.post('/upload', (c) => c.json({ rows: c.get('csv') }));
19
-
20
- app.get('/export', (c) => {
21
- const { csv, headers } = createCsvResponse([{ id: 1 }], 'export.csv');
22
- return c.text(csv, 200, headers);
23
- });
24
- ```
25
-
26
- ## Exports
27
- - csvMiddleware
28
- - createCsvResponse
@@ -1,12 +0,0 @@
1
- import type { CsvToJsonOptions, JsonToCsvOptions } from 'jtcsv';
2
- import type { Context } from 'hono';
3
-
4
- export function csvMiddleware(
5
- options?: CsvToJsonOptions
6
- ): (c: Context, next: () => Promise<void>) => Promise<void>;
7
-
8
- export function createCsvResponse(
9
- data: unknown[] | Record<string, unknown>,
10
- filename?: string,
11
- options?: JsonToCsvOptions
12
- ): { csv: string; headers: Record<string, string> };
@@ -1,36 +0,0 @@
1
- const jtcsv = require('jtcsv');
2
-
3
- function normalizeFilename(filename) {
4
- if (!filename || typeof filename !== 'string') {
5
- return 'export.csv';
6
- }
7
- return filename.includes('.') ? filename : `${filename}.csv`;
8
- }
9
-
10
- function csvMiddleware(options = {}) {
11
- return async (c, next) => {
12
- const csvText = await c.req.text();
13
- const rows = jtcsv.csvToJson(csvText, options);
14
- c.set('csv', rows);
15
- await next();
16
- };
17
- }
18
-
19
- function createCsvResponse(data, filename = 'export.csv', options = {}) {
20
- const safeName = normalizeFilename(filename);
21
- const rows = Array.isArray(data) ? data : [data];
22
- const csv = jtcsv.jsonToCsv(rows, options);
23
-
24
- return {
25
- csv,
26
- headers: {
27
- 'Content-Type': 'text/csv; charset=utf-8',
28
- 'Content-Disposition': `attachment; filename="${safeName}"`
29
- }
30
- };
31
- }
32
-
33
- module.exports = {
34
- csvMiddleware,
35
- createCsvResponse
36
- };
@@ -1,35 +0,0 @@
1
- {
2
- "name": "@jtcsv/hono",
3
- "version": "1.0.0",
4
- "description": "Hono middleware for JTCSV",
5
- "main": "index.js",
6
- "types": "index.d.ts",
7
- "keywords": [
8
- "hono",
9
- "csv",
10
- "json",
11
- "converter",
12
- "jtcsv",
13
- "middleware"
14
- ],
15
- "author": "Ruslan Fomenko",
16
- "license": "MIT",
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/Linol-Hamelton/jtcsv.git",
20
- "directory": "plugins/hono"
21
- },
22
- "bugs": {
23
- "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
24
- },
25
- "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/hono#readme",
26
- "peerDependencies": {
27
- "hono": "^4.0.0",
28
- "jtcsv": "^2.1.3"
29
- },
30
- "files": [
31
- "index.js",
32
- "index.d.ts",
33
- "README.md"
34
- ]
35
- }
@@ -1,35 +0,0 @@
1
- # @jtcsv/nestjs
2
-
3
- NestJS interceptors for parsing CSV payloads and returning CSV responses.
4
-
5
- ## Install
6
- ```bash
7
- npm install @jtcsv/nestjs jtcsv
8
- ```
9
-
10
- ## Usage
11
- ```typescript
12
- import { Controller, Post, Body, UseInterceptors } from '@nestjs/common';
13
- import { CsvParserInterceptor, CsvDownloadDecorator } from '@jtcsv/nestjs';
14
-
15
- @Controller('data')
16
- export class DataController {
17
- @Post('upload')
18
- @CsvParserInterceptor({ delimiter: ',' })
19
- upload(@Body() body: any[]) {
20
- return { rows: body };
21
- }
22
-
23
- @Post('export')
24
- @CsvDownloadDecorator({ filename: 'export.csv' })
25
- exportCsv() {
26
- return [{ id: 1, name: 'Jane' }];
27
- }
28
- }
29
- ```
30
-
31
- ## Exports
32
- - CsvParserInterceptor
33
- - CsvDownloadDecorator
34
- - createCsvParserInterceptor
35
- - createCsvDownloadInterceptor
@@ -1,25 +0,0 @@
1
- import type { Type } from '@nestjs/common';
2
- import type { NestInterceptor } from '@nestjs/common';
3
- import type { CsvToJsonOptions, JsonToCsvOptions } from 'jtcsv';
4
-
5
- export interface CsvParserOptions extends CsvToJsonOptions {}
6
-
7
- export interface CsvDownloadOptions extends JsonToCsvOptions {
8
- filename?: string;
9
- }
10
-
11
- export function createCsvParserInterceptor(
12
- options?: CsvParserOptions
13
- ): Type<NestInterceptor>;
14
-
15
- export function createCsvDownloadInterceptor(
16
- options?: CsvDownloadOptions
17
- ): Type<NestInterceptor>;
18
-
19
- export function CsvParserInterceptor(
20
- options?: CsvParserOptions
21
- ): MethodDecorator & ClassDecorator;
22
-
23
- export function CsvDownloadDecorator(
24
- options?: CsvDownloadOptions
25
- ): MethodDecorator & ClassDecorator;