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,136 +0,0 @@
1
- /**
2
- * Пример использования Express middleware для JTCSV
3
- *
4
- * Запуск: node example.js
5
- * Затем отправьте запросы:
6
- * - POST /api/convert с JSON телом → получите CSV
7
- * - POST /api/convert с CSV телом → получите JSON
8
- * - POST /api/csv-to-json → конвертация CSV в JSON
9
- * - POST /api/json-to-csv → конвертация JSON в CSV
10
- * - GET /api/health → проверка состояния
11
- */
12
-
13
- const express = require('express');
14
- const bodyParser = require('body-parser');
15
- const {
16
- middleware,
17
- csvToJsonRoute,
18
- jsonToCsvRoute,
19
- healthCheck
20
- } = require('./index');
21
-
22
- const app = express();
23
- const PORT = process.env.PORT || 3000;
24
-
25
- // Middleware для парсинга JSON и текста
26
- app.use(bodyParser.json());
27
- app.use(bodyParser.text({ type: 'text/csv' }));
28
-
29
- // Добавляем время начала обработки запроса
30
- app.use((req, res, next) => {
31
- req.startTime = Date.now();
32
- next();
33
- });
34
-
35
- // Основное middleware для автоматической конвертации
36
- app.use(middleware({
37
- maxSize: '50mb',
38
- delimiter: ',',
39
- enableFastPath: true,
40
- preventCsvInjection: true
41
- }));
42
-
43
- // Роуты для конкретных операций
44
- app.post('/api/csv-to-json', csvToJsonRoute({
45
- delimiter: ',',
46
- parseNumbers: true,
47
- parseBooleans: true
48
- }));
49
-
50
- app.post('/api/json-to-csv', jsonToCsvRoute({
51
- delimiter: ',',
52
- includeHeaders: true,
53
- preventCsvInjection: true
54
- }));
55
-
56
- // Health check
57
- app.get('/api/health', healthCheck());
58
-
59
- // Пример роута, использующего автоматическую конвертацию
60
- app.post('/api/convert', (req, res) => {
61
- if (!req.converted) {
62
- return res.status(400).json({
63
- success: false,
64
- error: 'No data to convert'
65
- });
66
- }
67
-
68
- res.json({
69
- success: true,
70
- conversion: req.converted.conversion,
71
- data: req.converted.data,
72
- stats: {
73
- ...req.converted.stats,
74
- totalTime: Date.now() - req.startTime
75
- },
76
- format: req.converted.outputFormat
77
- });
78
- });
79
-
80
- // Пример роута для скачивания CSV
81
- app.post('/api/download-csv', (req, res) => {
82
- if (!req.converted || req.converted.outputFormat !== 'csv') {
83
- return res.status(400).json({
84
- success: false,
85
- error: 'CSV data not available'
86
- });
87
- }
88
-
89
- res.setHeader('Content-Type', 'text/csv');
90
- res.setHeader('Content-Disposition', 'attachment; filename="converted.csv"');
91
- res.send(req.converted.data);
92
- });
93
-
94
- // Обработка ошибок
95
- app.use((err, req, res, next) => {
96
- console.error('Server error:', err);
97
- res.status(500).json({
98
- success: false,
99
- error: 'Internal server error',
100
- message: process.env.NODE_ENV === 'development' ? err.message : undefined
101
- });
102
- });
103
-
104
- // 404 handler
105
- app.use((req, res) => {
106
- res.status(404).json({
107
- success: false,
108
- error: 'Route not found',
109
- availableRoutes: [
110
- 'POST /api/convert',
111
- 'POST /api/csv-to-json',
112
- 'POST /api/json-to-csv',
113
- 'POST /api/download-csv',
114
- 'GET /api/health'
115
- ]
116
- });
117
- });
118
-
119
- // Запуск сервера
120
- app.listen(PORT, () => {
121
- console.log(`🚀 JTCSV Express server запущен на порту ${PORT}`);
122
- console.log(`📚 Примеры запросов:`);
123
- console.log(` curl -X POST http://localhost:${PORT}/api/convert \
124
- -H "Content-Type: application/json" \
125
- -d '[{"name":"John","age":30},{"name":"Jane","age":25}]'`);
126
- console.log();
127
- console.log(` curl -X POST http://localhost:${PORT}/api/convert \
128
- -H "Content-Type: text/csv" \
129
- -d 'name,age\nJohn,30\nJane,25'`);
130
- console.log();
131
- console.log(` curl -X GET http://localhost:${PORT}/api/health`);
132
- });
133
-
134
- module.exports = app;
135
-
136
-
@@ -1,114 +0,0 @@
1
- /**
2
- * TypeScript definitions для JTCSV Express Middleware
3
- *
4
- * @version 1.0.0
5
- * @date 2026-01-23
6
- */
7
-
8
- declare module '@jtcsv/express-middleware' {
9
- import { RequestHandler } from 'express';
10
- import { CsvToJsonOptions, JsonToCsvOptions } from 'jtcsv
11
-
12
- export interface JtcsvMiddlewareOptions {
13
- /** Максимальный размер тела запроса */
14
- maxSize?: string;
15
-
16
- /** Автоматическое определение формата */
17
- autoDetect?: boolean;
18
-
19
- /** Разделитель CSV */
20
- delimiter?: string;
21
-
22
- /** Включить Fast-Path Engine */
23
- enableFastPath?: boolean;
24
-
25
- /** Защита от CSV инъекций */
26
- preventCsvInjection?: boolean;
27
-
28
- /** Соответствие RFC 4180 */
29
- rfc4180Compliant?: boolean;
30
-
31
- /** Дополнительные опции конвертации */
32
- conversionOptions?: CsvToJsonOptions | JsonToCsvOptions;
33
- }
34
-
35
- export interface ConversionStats {
36
- /** Размер входных данных в байтах */
37
- inputSize: number;
38
-
39
- /** Размер выходных данных в байтах */
40
- outputSize: number;
41
-
42
- /** Время обработки в миллисекундах */
43
- processingTime: number;
44
-
45
- /** Тип конвертации */
46
- conversion: string;
47
- }
48
-
49
- export interface ConvertedData {
50
- /** Конвертированные данные */
51
- data: any;
52
-
53
- /** Формат выходных данных */
54
- format: 'json' | 'csv';
55
-
56
- /** Формат входных данных */
57
- inputFormat: 'json' | 'csv' | 'unknown';
58
-
59
- /** Формат выходных данных */
60
- outputFormat: 'json' | 'csv';
61
-
62
- /** Статистика конвертации */
63
- stats: ConversionStats;
64
-
65
- /** Использованные опции */
66
- options: CsvToJsonOptions | JsonToCsvOptions;
67
- }
68
-
69
- // Расширяем интерфейс Request Express
70
- declare global {
71
- namespace Express {
72
- interface Request {
73
- /** Конвертированные данные */
74
- converted?: ConvertedData;
75
-
76
- /** Время начала обработки запроса */
77
- startTime?: number;
78
- }
79
- }
80
- }
81
-
82
- /**
83
- * Express middleware для автоматической конвертации CSV/JSON
84
- */
85
- export function middleware(options?: JtcsvMiddlewareOptions): RequestHandler;
86
-
87
- /**
88
- * Express route для конвертации CSV в JSON
89
- */
90
- export function csvToJsonRoute(options?: CsvToJsonOptions): RequestHandler;
91
-
92
- /**
93
- * Express route для конвертации JSON в CSV
94
- */
95
- export function jsonToCsvRoute(options?: JsonToCsvOptions): RequestHandler;
96
-
97
- /**
98
- * Express route для загрузки CSV файла
99
- */
100
- export function uploadCsvRoute(options?: CsvToJsonOptions): RequestHandler;
101
-
102
- /**
103
- * Health check endpoint
104
- */
105
- export function healthCheck(): RequestHandler;
106
-
107
- // Aliases
108
- export const jtcsvMiddleware: typeof middleware;
109
- export const createMiddleware: typeof middleware;
110
- }
111
-
112
- export {};
113
-
114
-
@@ -1,360 +0,0 @@
1
- /**
2
- * Express middleware для JTCSV
3
- * Автоматическая конвертация CSV/JSON в HTTP запросах
4
- *
5
- * @version 1.0.0
6
- * @date 2026-01-23
7
- */
8
-
9
- const { csvToJson, jsonToCsv } = require('../../index.js');
10
-
11
- /**
12
- * Express middleware для обработки CSV/JSON конвертации
13
- *
14
- * @param {Object} options - Опции middleware
15
- * @param {string} options.maxSize - Максимальный размер тела запроса (default: '10mb')
16
- * @param {boolean} options.autoDetect - Автоматическое определение формата (default: true)
17
- * @param {string} options.delimiter - Разделитель CSV (default: ',')
18
- * @param {boolean} options.enableFastPath - Включить Fast-Path Engine (default: true)
19
- * @param {boolean} options.preventCsvInjection - Защита от CSV инъекций (default: true)
20
- *
21
- * @returns {Function} Express middleware
22
- *
23
- * @example
24
- * // Базовое использование
25
- * const app = express();
26
- * app.use(express.json());
27
- * app.use(express.text({ type: 'text/csv' }));
28
- * app.use(jtcsvMiddleware());
29
- *
30
- * @example
31
- * // С кастомными опциями
32
- * app.use(jtcsvMiddleware({
33
- * maxSize: '50mb',
34
- * delimiter: ';',
35
- * enableFastPath: true
36
- * }));
37
- *
38
- * @example
39
- * // Использование в роуте
40
- * app.post('/api/convert', (req, res) => {
41
- * // Конвертированные данные доступны в req.converted
42
- * res.json({
43
- * success: true,
44
- * data: req.converted.data,
45
- * format: req.converted.format
46
- * });
47
- * });
48
- */
49
- function jtcsvExpressMiddleware(options = {}) {
50
- const {
51
- maxSize = '10mb',
52
- autoDetect = true,
53
- delimiter = ',',
54
- enableFastPath = true,
55
- preventCsvInjection = true,
56
- rfc4180Compliant = true
57
- } = options;
58
-
59
- return async (req, res, next) => {
60
- // Пропускаем запросы без тела
61
- if (!req.body || (typeof req.body !== 'string' && typeof req.body !== 'object')) {
62
- return next();
63
- }
64
-
65
- const contentType = req.get('content-type') || '';
66
- const acceptHeader = req.get('accept') || 'application/json';
67
-
68
- try {
69
- // Определяем формат входных данных
70
- let inputFormat = 'unknown';
71
- let inputData = req.body;
72
-
73
- if (autoDetect) {
74
- if (contentType.includes('application/json') ||
75
- (typeof req.body === 'object' && !Array.isArray(req.body))) {
76
- inputFormat = 'json';
77
- } else if (contentType.includes('text/csv') ||
78
- contentType.includes('text/plain') ||
79
- (typeof req.body === 'string' && req.body.includes(','))) {
80
- inputFormat = 'csv';
81
- }
82
- } else {
83
- // Ручное определение на основе content-type
84
- if (contentType.includes('application/json')) {
85
- inputFormat = 'json';
86
- } else if (contentType.includes('text/csv')) {
87
- inputFormat = 'csv';
88
- }
89
- }
90
-
91
- // Если формат не определен, пропускаем
92
- if (inputFormat === 'unknown') {
93
- return next();
94
- }
95
-
96
- // Определяем желаемый формат вывода на основе Accept header
97
- let outputFormat = 'json';
98
- if (acceptHeader.includes('text/csv')) {
99
- outputFormat = 'csv';
100
- } else if (req.query.format === 'csv') {
101
- outputFormat = 'csv';
102
- } else if (req.body.format === 'csv') {
103
- outputFormat = 'csv';
104
- }
105
-
106
- // Опции конвертации
107
- const conversionOptions = {
108
- delimiter,
109
- preventCsvInjection,
110
- rfc4180Compliant,
111
- useFastPath: enableFastPath,
112
- ...req.query,
113
- ...options.conversionOptions
114
- };
115
-
116
- // Удаляем параметры, которые не относятся к конвертации
117
- delete conversionOptions.maxSize;
118
- delete conversionOptions.autoDetect;
119
- delete conversionOptions.enableFastPath;
120
-
121
- let result;
122
- let stats = {
123
- inputSize: 0,
124
- outputSize: 0,
125
- processingTime: 0,
126
- conversion: `${inputFormat}→${outputFormat}`
127
- };
128
-
129
- const startTime = Date.now();
130
-
131
- // Выполняем конвертацию
132
- if (inputFormat === 'json' && outputFormat === 'csv') {
133
- const jsonData = typeof inputData === 'string' ? JSON.parse(inputData) : inputData;
134
- stats.inputSize = Buffer.byteLength(JSON.stringify(jsonData));
135
-
136
- result = await jsonToCsv(jsonData, conversionOptions);
137
- stats.outputSize = Buffer.byteLength(result);
138
-
139
- } else if (inputFormat === 'csv' && outputFormat === 'json') {
140
- const csvData = typeof inputData === 'string' ? inputData : String(inputData);
141
- stats.inputSize = Buffer.byteLength(csvData);
142
-
143
- result = await csvToJson(csvData, conversionOptions);
144
- stats.outputSize = Buffer.byteLength(JSON.stringify(result));
145
-
146
- } else {
147
- // Нет необходимости в конвертации
148
- result = inputData;
149
- stats.conversion = 'none';
150
- }
151
-
152
- stats.processingTime = Date.now() - startTime;
153
-
154
- // Сохраняем результат в request object
155
- req.converted = {
156
- data: result,
157
- format: outputFormat,
158
- inputFormat,
159
- outputFormat,
160
- stats,
161
- options: conversionOptions
162
- };
163
-
164
- // Устанавливаем соответствующий Content-Type для ответа
165
- if (outputFormat === 'csv') {
166
- res.set('Content-Type', 'text/csv; charset=utf-8');
167
- } else {
168
- res.set('Content-Type', 'application/json; charset=utf-8');
169
- }
170
-
171
- next();
172
-
173
- } catch (error) {
174
- // Обработка ошибок конвертации
175
- const errorResponse = {
176
- success: false,
177
- error: error.message,
178
- code: error.code || 'CONVERSION_ERROR',
179
- timestamp: new Date().toISOString()
180
- };
181
-
182
- // Добавляем дополнительную информацию для отладки
183
- if (process.env.NODE_ENV === 'development') {
184
- errorResponse.stack = error.stack;
185
- errorResponse.details = {
186
- contentType: req.get('content-type'),
187
- contentLength: req.get('content-length'),
188
- method: req.method,
189
- url: req.url
190
- };
191
- }
192
-
193
- res.status(400).json(errorResponse);
194
- }
195
- };
196
- }
197
-
198
- /**
199
- * Express route для конвертации CSV в JSON
200
- *
201
- * @param {Object} options - Опции конвертации
202
- * @returns {Function} Express route handler
203
- *
204
- * @example
205
- * app.post('/api/csv-to-json', jtcsvCsvToJsonRoute());
206
- */
207
- function jtcsvCsvToJsonRoute(options = {}) {
208
- return async (req, res) => {
209
- try {
210
- const csvData = req.body;
211
-
212
- if (!csvData || (typeof csvData !== 'string' && !Buffer.isBuffer(csvData))) {
213
- return res.status(400).json({
214
- success: false,
215
- error: 'CSV data is required'
216
- });
217
- }
218
-
219
- const result = await csvToJson(csvData, options);
220
-
221
- res.json({
222
- success: true,
223
- data: result,
224
- stats: {
225
- rows: result.length,
226
- processingTime: Date.now() - req.startTime
227
- }
228
- });
229
- } catch (error) {
230
- res.status(400).json({
231
- success: false,
232
- error: error.message
233
- });
234
- }
235
- };
236
- }
237
-
238
- /**
239
- * Express route для конвертации JSON в CSV
240
- *
241
- * @param {Object} options - Опции конвертации
242
- * @returns {Function} Express route handler
243
- *
244
- * @example
245
- * app.post('/api/json-to-csv', jtcsvJsonToCsvRoute());
246
- */
247
- function jtcsvJsonToCsvRoute(options = {}) {
248
- return async (req, res) => {
249
- try {
250
- const jsonData = req.body;
251
-
252
- if (!jsonData || (typeof jsonData !== 'object' && typeof jsonData !== 'string')) {
253
- return res.status(400).json({
254
- success: false,
255
- error: 'JSON data is required'
256
- });
257
- }
258
-
259
- const data = typeof jsonData === 'string' ? JSON.parse(jsonData) : jsonData;
260
- const result = await jsonToCsv(data, options);
261
-
262
- res.set('Content-Type', 'text/csv; charset=utf-8');
263
- res.set('Content-Disposition', 'attachment; filename="data.csv"');
264
-
265
- res.send(result);
266
- } catch (error) {
267
- res.status(400).json({
268
- success: false,
269
- error: error.message
270
- });
271
- }
272
- };
273
- }
274
-
275
- /**
276
- * Express route для загрузки CSV файла
277
- *
278
- * @param {Object} options - Опции конвертации
279
- * @returns {Function} Express route handler
280
- *
281
- * @example
282
- * const multer = require('multer');
283
- * const upload = multer({ dest: 'uploads/' });
284
- * app.post('/api/upload-csv', upload.single('file'), jtcsvUploadCsvRoute());
285
- */
286
- function jtcsvUploadCsvRoute(options = {}) {
287
- return async (req, res) => {
288
- try {
289
- if (!req.file) {
290
- return res.status(400).json({
291
- success: false,
292
- error: 'CSV file is required'
293
- });
294
- }
295
-
296
- const fs = require('fs').promises;
297
- const csvData = await fs.readFile(req.file.path, 'utf8');
298
-
299
- const result = await csvToJson(csvData, options);
300
-
301
- // Очищаем временный файл
302
- await fs.unlink(req.file.path);
303
-
304
- res.json({
305
- success: true,
306
- data: result,
307
- stats: {
308
- rows: result.length,
309
- fileSize: req.file.size,
310
- processingTime: Date.now() - req.startTime
311
- }
312
- });
313
- } catch (error) {
314
- res.status(400).json({
315
- success: false,
316
- error: error.message
317
- });
318
- }
319
- };
320
- }
321
-
322
- /**
323
- * Health check endpoint для JTCSV
324
- *
325
- * @returns {Function} Express route handler
326
- *
327
- * @example
328
- * app.get('/api/health', jtcsvHealthCheck());
329
- */
330
- function jtcsvHealthCheck() {
331
- return (req, res) => {
332
- res.json({
333
- service: 'jtcsv-express-middleware',
334
- status: 'healthy',
335
- version: '1.0.0',
336
- timestamp: new Date().toISOString(),
337
- features: {
338
- csvToJson: true,
339
- jsonToCsv: true,
340
- fastPathEngine: true,
341
- csvInjectionProtection: true,
342
- streaming: true
343
- }
344
- });
345
- };
346
- }
347
-
348
- module.exports = {
349
- middleware: jtcsvExpressMiddleware,
350
- csvToJsonRoute: jtcsvCsvToJsonRoute,
351
- jsonToCsvRoute: jtcsvJsonToCsvRoute,
352
- uploadCsvRoute: jtcsvUploadCsvRoute,
353
- healthCheck: jtcsvHealthCheck,
354
-
355
- // Aliases для удобства
356
- jtcsvMiddleware: jtcsvExpressMiddleware,
357
- createMiddleware: jtcsvExpressMiddleware
358
- };
359
-
360
-
@@ -1,52 +0,0 @@
1
- {
2
- "name": "@jtcsv/express-middleware",
3
- "version": "1.0.0",
4
- "description": "Express middleware для автоматической конвертации CSV/JSON в HTTP запросах",
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
- "express",
14
- "middleware",
15
- "csv",
16
- "json",
17
- "converter",
18
- "jtcsv",
19
- "api",
20
- "rest",
21
- "http"
22
- ],
23
- "author": "Ruslan Fomenko",
24
- "license": "MIT",
25
- "repository": {
26
- "type": "git",
27
- "url": "git+https://github.com/Linol-Hamelton/jtcsv.git",
28
- "directory": "plugins/express-middleware"
29
- },
30
- "bugs": {
31
- "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
32
- },
33
- "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/express-middleware#readme",
34
- "peerDependencies": {
35
- "express": "^4.18.0",
36
- "jtcsv": "^2.1.0"
37
- },
38
- "devDependencies": {
39
- "express": "^4.18.0",
40
- "jest": "^29.0.0",
41
- "eslint": "^8.57.0",
42
- "supertest": "^6.3.0"
43
- },
44
- "files": [
45
- "index.js",
46
- "index.d.ts",
47
- "README.md",
48
- "example.js"
49
- ]
50
- }
51
-
52
-