jtcsv 2.1.1 → 2.1.5

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 (60) hide show
  1. package/README.md +64 -327
  2. package/bin/jtcsv.js +7 -24
  3. package/csv-to-json.js +35 -26
  4. package/dist/jtcsv.cjs.js +807 -133
  5. package/dist/jtcsv.cjs.js.map +1 -1
  6. package/dist/jtcsv.esm.js +800 -134
  7. package/dist/jtcsv.esm.js.map +1 -1
  8. package/dist/jtcsv.umd.js +807 -133
  9. package/dist/jtcsv.umd.js.map +1 -1
  10. package/errors.js +20 -0
  11. package/examples/browser-vanilla.html +37 -0
  12. package/examples/cli-batch-processing.js +38 -0
  13. package/examples/simple-usage.js +12 -10
  14. package/examples/web-workers-advanced.js +28 -0
  15. package/json-save.js +2 -1
  16. package/package.json +41 -21
  17. package/plugins/README.md +50 -332
  18. package/plugins/express-middleware/README.md +32 -274
  19. package/plugins/hono/README.md +28 -0
  20. package/plugins/hono/index.d.ts +12 -0
  21. package/plugins/hono/index.js +36 -0
  22. package/plugins/hono/package.json +35 -0
  23. package/plugins/nestjs/README.md +35 -0
  24. package/plugins/nestjs/index.d.ts +25 -0
  25. package/plugins/nestjs/index.js +77 -0
  26. package/plugins/nestjs/package.json +37 -0
  27. package/plugins/nextjs-api/README.md +28 -423
  28. package/plugins/nextjs-api/index.js +1 -2
  29. package/plugins/nextjs-api/route.js +1 -2
  30. package/plugins/nuxt/README.md +24 -0
  31. package/plugins/nuxt/index.js +21 -0
  32. package/plugins/nuxt/package.json +35 -0
  33. package/plugins/nuxt/runtime/composables/useJtcsv.js +6 -0
  34. package/plugins/nuxt/runtime/plugin.js +6 -0
  35. package/plugins/remix/README.md +26 -0
  36. package/plugins/remix/index.d.ts +16 -0
  37. package/plugins/remix/index.js +62 -0
  38. package/plugins/remix/package.json +35 -0
  39. package/plugins/sveltekit/README.md +28 -0
  40. package/plugins/sveltekit/index.d.ts +17 -0
  41. package/plugins/sveltekit/index.js +54 -0
  42. package/plugins/sveltekit/package.json +33 -0
  43. package/plugins/trpc/README.md +25 -0
  44. package/plugins/trpc/index.d.ts +7 -0
  45. package/plugins/trpc/index.js +32 -0
  46. package/plugins/trpc/package.json +34 -0
  47. package/src/browser/browser-functions.js +33 -3
  48. package/src/browser/csv-to-json-browser.js +269 -11
  49. package/src/browser/errors-browser.js +19 -1
  50. package/src/browser/index.js +39 -5
  51. package/src/browser/streams.js +393 -0
  52. package/src/browser/workers/csv-parser.worker.js +20 -2
  53. package/src/browser/workers/worker-pool.js +507 -447
  54. package/src/core/plugin-system.js +4 -0
  55. package/src/engines/fast-path-engine.js +31 -23
  56. package/src/formats/ndjson-parser.js +54 -5
  57. package/src/formats/tsv-parser.js +4 -1
  58. package/stream-csv-to-json.js +11 -2
  59. package/stream-json-to-csv.js +13 -1
  60. package/cli-tui.js +0 -1498
@@ -1,452 +1,57 @@
1
1
  # @jtcsv/nextjs
2
2
 
3
- Next.js интеграция для JTCSV - API routes, React hooks и компоненты для конвертации CSV/JSON.
4
-
5
- ## 📦 Установка
3
+ Next.js helpers for JTCSV: API route handler, React hooks, and browser helpers.
6
4
 
5
+ ## Install
7
6
  ```bash
8
7
  npm install @jtcsv/nextjs jtcsv
9
- # или
10
- pnpm add @jtcsv/nextjs jtcsv
11
- # или
12
- yarn add @jtcsv/nextjs jtcsv
13
8
  ```
14
9
 
15
- ## 🚀 Быстрый старт
16
-
17
- ### 1. API Route
18
-
19
- Создайте файл `pages/api/convert.js`:
20
-
10
+ ## API route
21
11
  ```javascript
22
12
  // pages/api/convert.js
23
- import { handler } from '@jtcsv/nextjs/route';
13
+ import handler from '@jtcsv/nextjs/route';
24
14
 
25
15
  export default handler;
26
-
27
- export const config = {
28
- api: {
29
- bodyParser: {
30
- sizeLimit: '50mb'
31
- }
32
- }
33
- };
34
16
  ```
35
17
 
36
- ### 2. React компонент
18
+ Query options handled by the route:
19
+ - format: json|csv
20
+ - delimiter
21
+ - includeHeaders
22
+ - parseNumbers
23
+ - parseBooleans
24
+ - useFastPath
25
+ - preventCsvInjection
37
26
 
27
+ ## React hook
38
28
  ```jsx
39
- // components/Converter.jsx
40
29
  'use client';
41
-
42
30
  import { useJtcsv } from '@jtcsv/nextjs';
43
31
 
44
32
  export default function Converter() {
45
- const {
46
- convertCsvToJson,
47
- convertJsonToCsv,
48
- isLoading,
49
- error,
50
- result
51
- } = useJtcsv();
52
-
53
- const handleConvert = async () => {
54
- const csv = 'name,age\nJohn,30\nJane,25';
55
- const json = await convertCsvToJson(csv);
56
- console.log('Converted:', json);
57
- };
58
-
59
- return (
60
- <div>
61
- <button onClick={handleConvert} disabled={isLoading}>
62
- {isLoading ? 'Converting...' : 'Convert CSV to JSON'}
63
- </button>
64
- {error && <div>Error: {error}</div>}
65
- {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
66
- </div>
67
- );
33
+ const { convertCsvToJson, convertJsonToCsv, isLoading, error, result } = useJtcsv();
34
+ return null;
68
35
  }
69
36
  ```
70
37
 
71
- ## 📖 Документация
72
-
73
- ### API Routes
74
-
75
- #### Автоматическая конвертация
76
-
38
+ ## Components and utilities
77
39
  ```javascript
78
- // pages/api/convert.js
79
- import { handler } from '@jtcsv/nextjs/route';
80
-
81
- export default handler;
82
- ```
83
-
84
- **Примеры запросов:**
85
-
86
- ```bash
87
- # JSON → CSV
88
- curl -X POST http://localhost:3000/api/convert \
89
- -H "Content-Type: application/json" \
90
- -d '[{"name":"John","age":30}]'
91
-
92
- # CSV → JSON
93
- curl -X POST http://localhost:3000/api/convert \
94
- -H "Content-Type: text/csv" \
95
- -d 'name,age\nJohn,30\nJane,25'
96
-
97
- # Специфичный формат вывода
98
- curl -X POST "http://localhost:3000/api/convert?format=csv" \
99
- -H "Content-Type: application/json" \
100
- -d '[{"name":"John","age":30}]'
40
+ import {
41
+ CsvFileUploader,
42
+ downloadCsv,
43
+ createJtcsvApiClient,
44
+ JtcsvProvider,
45
+ useJtcsvContext
46
+ } from '@jtcsv/nextjs';
101
47
  ```
102
48
 
103
- #### Специализированные handlers
104
-
49
+ ## Route helpers
105
50
  ```javascript
106
- // pages/api/convert/[...path].js
107
- import {
51
+ import {
108
52
  csvToJsonHandler,
109
53
  jsonToCsvHandler,
110
- healthCheckHandler
54
+ healthCheckHandler,
55
+ createJtcsvApiEndpoint
111
56
  } from '@jtcsv/nextjs/route';
112
-
113
- export default async function handler(req, res) {
114
- const { path } = req.query;
115
-
116
- switch (path?.[0]) {
117
- case 'csv-to-json':
118
- return csvToJsonHandler(req, res);
119
- case 'json-to-csv':
120
- return jsonToCsvHandler(req, res);
121
- case 'health':
122
- return healthCheckHandler(req, res);
123
- default:
124
- res.status(404).json({ error: 'Not found' });
125
- }
126
- }
127
- ```
128
-
129
- ### React Hooks
130
-
131
- #### useJtcsv
132
-
133
- ```jsx
134
- import { useJtcsv } from '@jtcsv/nextjs';
135
-
136
- function Converter() {
137
- const {
138
- convertCsvToJson,
139
- convertJsonToCsv,
140
- isLoading,
141
- error,
142
- result,
143
- stats,
144
- reset
145
- } = useJtcsv({
146
- delimiter: ',', // Разделитель CSV
147
- parseNumbers: true, // Парсить числа
148
- parseBooleans: true, // Парсить булевы значения
149
- preventCsvInjection: true // Защита от инъекций
150
- });
151
-
152
- // ...
153
- }
154
- ```
155
-
156
- #### JtcsvProvider (Context)
157
-
158
- ```jsx
159
- // app/layout.jsx
160
- import { JtcsvProvider } from '@jtcsv/nextjs';
161
-
162
- export default function Layout({ children }) {
163
- return (
164
- <JtcsvProvider options={{ delimiter: ',' }}>
165
- {children}
166
- </JtcsvProvider>
167
- );
168
- }
169
-
170
- // components/Converter.jsx
171
- 'use client';
172
- import { useJtcsvContext } from '@jtcsv/nextjs';
173
-
174
- export default function Converter() {
175
- const { csvToJson, jsonToCsv } = useJtcsvContext();
176
- // ...
177
- }
178
- ```
179
-
180
- ### Компоненты
181
-
182
- #### CsvFileUploader
183
-
184
- ```jsx
185
- import { CsvFileUploader } from '@jtcsv/nextjs';
186
-
187
- function FileUpload() {
188
- const handleConvert = (result, stats) => {
189
- console.log('Converted:', result);
190
- console.log('Stats:', stats);
191
- };
192
-
193
- return (
194
- <CsvFileUploader
195
- onConvert={handleConvert}
196
- options={{ delimiter: ',' }}
197
- >
198
- <button>📁 Upload CSV File</button>
199
- </CsvFileUploader>
200
- );
201
- }
202
- ```
203
-
204
- ### Утилиты
205
-
206
- #### downloadCsv
207
-
208
- ```javascript
209
- import { downloadCsv } from '@jtcsv/nextjs';
210
-
211
- const data = [{ name: 'John', age: 30 }];
212
- await downloadCsv(data, 'users.csv', { delimiter: ',' });
213
- ```
214
-
215
- #### createJtcsvApiClient
216
-
217
- ```javascript
218
- import { createJtcsvApiClient } from '@jtcsv/nextjs';
219
-
220
- const api = createJtcsvApiClient('/api/convert');
221
-
222
- // Конвертация CSV в JSON
223
- const json = await api.csvToJson('name,age\nJohn,30');
224
-
225
- // Конвертация JSON в CSV
226
- const csv = await api.jsonToCsv([{ name: 'John', age: 30 }]);
227
-
228
- // Проверка здоровья
229
- const health = await api.health();
230
- ```
231
-
232
- ## 🔧 Конфигурация
233
-
234
- ### Опции API Route
235
-
236
- | Параметр | Тип | По умолчанию | Описание |
237
- |----------|-----|--------------|----------|
238
- | `format` | `string` | `auto` | Формат вывода: `json`, `csv` |
239
- | `delimiter` | `string` | `','` | Разделитель CSV |
240
- | `includeHeaders` | `boolean` | `true` | Включать заголовки в CSV |
241
- | `parseNumbers` | `boolean` | `true` | Парсить числа |
242
- | `parseBooleans` | `boolean` | `true` | Парсить булевы значения |
243
- | `useFastPath` | `boolean` | `true` | Использовать Fast-Path Engine |
244
- | `preventCsvInjection` | `boolean` | `true` | Защита от CSV инъекций |
245
-
246
- ### Опции React Hook
247
-
248
- ```javascript
249
- const options = {
250
- delimiter: ',', // Разделитель CSV
251
- includeHeaders: true, // Включать заголовки
252
- parseNumbers: true, // Парсить числа
253
- parseBooleans: true, // Парсить булевы значения
254
- useFastPath: true, // Использовать Fast-Path Engine
255
- preventCsvInjection: true,// Защита от инъекций
256
- rfc4180Compliant: true // Соответствие RFC 4180
257
- };
258
- ```
259
-
260
- ## 🌐 Примеры
261
-
262
- ### Полный пример приложения
263
-
264
- Смотрите `examples/ConverterComponent.jsx` для полного примера React компонента.
265
-
266
- ### Кастомная API Route
267
-
268
- ```javascript
269
- // pages/api/convert/secure.js
270
- import { handler } from '@jtcsv/nextjs/route';
271
-
272
- export default async function secureHandler(req, res) {
273
- // Проверка API ключа
274
- const apiKey = req.headers['x-api-key'];
275
- if (apiKey !== process.env.API_KEY) {
276
- return res.status(401).json({ error: 'Unauthorized' });
277
- }
278
-
279
- // Rate limiting
280
- const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
281
- // ... ваша логика rate limiting
282
-
283
- // Логирование
284
- console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
285
-
286
- // Вызов основного обработчика
287
- return handler(req, res);
288
- }
289
-
290
- export const config = {
291
- api: {
292
- bodyParser: {
293
- sizeLimit: '10mb'
294
- }
295
- }
296
- };
297
- ```
298
-
299
- ### Интеграция с формой
300
-
301
- ```jsx
302
- 'use client';
303
- import { useState } from 'react';
304
- import { useJtcsv, downloadCsv } from '@jtcsv/nextjs';
305
-
306
- export default function DataForm() {
307
- const [data, setData] = useState([]);
308
- const { convertJsonToCsv } = useJtcsv();
309
-
310
- const handleSubmit = async (e) => {
311
- e.preventDefault();
312
-
313
- // Конвертируем данные в CSV
314
- const csv = await convertJsonToCsv(data);
315
-
316
- // Скачиваем файл
317
- await downloadCsv(data, 'form-data.csv');
318
-
319
- // Отправляем на сервер
320
- await fetch('/api/submit', {
321
- method: 'POST',
322
- headers: { 'Content-Type': 'application/json' },
323
- body: JSON.stringify({ csv, data })
324
- });
325
- };
326
-
327
- return (
328
- <form onSubmit={handleSubmit}>
329
- {/* поля формы */}
330
- <button type="submit">Submit and Download CSV</button>
331
- </form>
332
- );
333
- }
334
- ```
335
-
336
- ## 🛡️ Безопасность
337
-
338
- ### Защита от CSV инъекций
339
-
340
- Все конвертации по умолчанию защищены от CSV инъекций:
341
-
342
- ```javascript
343
- // Опасные данные
344
- const dangerous = [{ formula: '=1+1', command: '@echo hello' }];
345
-
346
- // Безопасный CSV
347
- const safeCsv = await jsonToCsv(dangerous, { preventCsvInjection: true });
348
- // Результат: "'=1+1','@echo hello"
349
- ```
350
-
351
- ### Валидация размера
352
-
353
- ```javascript
354
- // pages/api/convert.js
355
- export const config = {
356
- api: {
357
- bodyParser: {
358
- sizeLimit: '10mb' // Ограничение размера
359
- }
360
- }
361
- };
362
- ```
363
-
364
- ## 📊 Мониторинг
365
-
366
- ### Health Check
367
-
368
- ```bash
369
- curl http://localhost:3000/api/convert/health
370
- ```
371
-
372
- **Ответ:**
373
- ```json
374
- {
375
- "service": "jtcsv-nextjs-api",
376
- "status": "healthy",
377
- "version": "1.0.0",
378
- "timestamp": "2026-01-23T10:30:00.000Z",
379
- "features": {
380
- "csvToJson": true,
381
- "jsonToCsv": true,
382
- "fastPathEngine": true,
383
- "csvInjectionProtection": true,
384
- "streaming": true,
385
- "ndjson": true
386
- }
387
- }
388
- ```
389
-
390
- ### Статистика
391
-
392
- Каждая операция возвращает статистику:
393
-
394
- ```json
395
- {
396
- "stats": {
397
- "inputSize": 45,
398
- "outputSize": 28,
399
- "processingTime": 12,
400
- "conversion": "json→csv",
401
- "rows": 2
402
- }
403
- }
404
- ```
405
-
406
- ## 🔌 TypeScript
407
-
408
- Полная поддержка TypeScript:
409
-
410
- ```typescript
411
- import {
412
- useJtcsv,
413
- CsvFileUploader,
414
- type ConversionStats
415
- } from '@jtcsv/nextjs';
416
-
417
- interface MyComponentProps {
418
- onConvert: (result: any[], stats: ConversionStats) => void;
419
- }
420
- ```
421
-
422
- ## 🧪 Тестирование
423
-
424
- ```bash
425
- # Запуск примеров
426
- cd plugins/nextjs-api/examples
427
-
428
- # Тестовые запросы к API
429
- curl -X POST http://localhost:3000/api/convert \
430
- -H "Content-Type: application/json" \
431
- -d '[{"test":"data"}]'
432
- ```
433
-
434
- ## 📄 Лицензия
435
-
436
- MIT
437
-
438
- ## 🤝 Вклад в развитие
439
-
440
- 1. Форкните репозиторий
441
- 2. Создайте ветку для вашей функции
442
- 3. Закоммитьте изменения
443
- 4. Запушьте в ветку
444
- 5. Откройте Pull Request
445
-
446
- ## 📞 Поддержка
447
-
448
- - [Issues](https://github.com/Linol-Hamelton/jtcsv/issues)
449
- - [Discussions](https://github.com/Linol-Hamelton/jtcsv/discussions)
450
- - [Documentation](https://github.com/Linol-Hamelton/jtcsv#readme)
451
-
452
-
57
+ ```
@@ -6,7 +6,7 @@
6
6
  * @date 2026-01-23
7
7
  */
8
8
 
9
- import { csvToJson, jsonToCsv } from 'jtcsv
9
+ import { csvToJson, jsonToCsv } from 'jtcsv';
10
10
 
11
11
  export { csvToJson, jsonToCsv };
12
12
 
@@ -385,4 +385,3 @@ export function useJtcsvContext() {
385
385
  // Экспортируем все из route.js
386
386
  export * from './route';
387
387
 
388
-
@@ -10,7 +10,7 @@
10
10
  * 2. Или импортируйте функции в существующие API routes
11
11
  */
12
12
 
13
- import { csvToJson, jsonToCsv } from 'jtcsv
13
+ import { csvToJson, jsonToCsv } from 'jtcsv';
14
14
 
15
15
  /**
16
16
  * Конфигурация Next.js API route
@@ -369,4 +369,3 @@ export function createJtcsvApiEndpoint(options = {}) {
369
369
  };
370
370
  }
371
371
 
372
-
@@ -0,0 +1,24 @@
1
+ # @jtcsv/nuxt
2
+
3
+ Nuxt module that injects `jtcsv` into the Nuxt app and provides a `useJtcsv` composable.
4
+
5
+ ## Install
6
+ ```bash
7
+ npm install @jtcsv/nuxt jtcsv
8
+ ```
9
+
10
+ ## Nuxt config
11
+ ```typescript
12
+ export default defineNuxtConfig({
13
+ modules: ['@jtcsv/nuxt'],
14
+ jtcsv: { autoimport: true }
15
+ });
16
+ ```
17
+
18
+ ## Usage
19
+ ```vue
20
+ <script setup>
21
+ const jtcsv = useJtcsv();
22
+ const csv = jtcsv.jsonToCsv([{ id: 1 }]);
23
+ </script>
24
+ ```
@@ -0,0 +1,21 @@
1
+ const { defineNuxtModule, addPlugin, addImports, createResolver } = require('@nuxt/kit');
2
+
3
+ module.exports = defineNuxtModule({
4
+ meta: {
5
+ name: '@jtcsv/nuxt',
6
+ configKey: 'jtcsv'
7
+ },
8
+ defaults: {
9
+ autoimport: true
10
+ },
11
+ setup(options) {
12
+ const resolver = createResolver(__dirname);
13
+ addPlugin(resolver.resolve('runtime/plugin'));
14
+
15
+ if (options.autoimport !== false) {
16
+ addImports([
17
+ { name: 'useJtcsv', from: resolver.resolve('runtime/composables/useJtcsv') }
18
+ ]);
19
+ }
20
+ }
21
+ });
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@jtcsv/nuxt",
3
+ "version": "1.0.0",
4
+ "description": "Nuxt module for JTCSV (auto-imported composable)",
5
+ "main": "index.js",
6
+ "keywords": [
7
+ "nuxt",
8
+ "module",
9
+ "csv",
10
+ "json",
11
+ "converter",
12
+ "jtcsv"
13
+ ],
14
+ "author": "Ruslan Fomenko",
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/Linol-Hamelton/jtcsv.git",
19
+ "directory": "plugins/nuxt"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
23
+ },
24
+ "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/nuxt#readme",
25
+ "peerDependencies": {
26
+ "@nuxt/kit": "^3.0.0",
27
+ "jtcsv": "^2.1.3",
28
+ "nuxt": "^3.0.0"
29
+ },
30
+ "files": [
31
+ "index.js",
32
+ "README.md",
33
+ "runtime/"
34
+ ]
35
+ }
@@ -0,0 +1,6 @@
1
+ import { useNuxtApp } from '#app';
2
+
3
+ export const useJtcsv = () => {
4
+ const { $jtcsv } = useNuxtApp();
5
+ return $jtcsv;
6
+ };
@@ -0,0 +1,6 @@
1
+ import { defineNuxtPlugin } from '#app';
2
+ import * as jtcsv from 'jtcsv';
3
+
4
+ export default defineNuxtPlugin((nuxtApp) => {
5
+ nuxtApp.provide('jtcsv', jtcsv);
6
+ });
@@ -0,0 +1,26 @@
1
+ # @jtcsv/remix
2
+
3
+ Remix helpers for CSV form uploads and CSV responses.
4
+
5
+ ## Install
6
+ ```bash
7
+ npm install @jtcsv/remix jtcsv
8
+ ```
9
+
10
+ ## Usage
11
+ ```javascript
12
+ import { parseFormData, generateCsvResponse } from '@jtcsv/remix';
13
+
14
+ export async function action({ request }) {
15
+ const rows = await parseFormData(request, { fieldName: 'file', delimiter: ',' });
16
+ return { rows };
17
+ }
18
+
19
+ export async function loader() {
20
+ return generateCsvResponse([{ id: 1 }], 'export.csv');
21
+ }
22
+ ```
23
+
24
+ ## Exports
25
+ - parseFormData
26
+ - generateCsvResponse
@@ -0,0 +1,16 @@
1
+ import type { CsvToJsonOptions, JsonToCsvOptions } from 'jtcsv';
2
+
3
+ export interface RemixCsvParseOptions extends CsvToJsonOptions {
4
+ fieldName?: string;
5
+ }
6
+
7
+ export function parseFormData(
8
+ request: Request,
9
+ options?: RemixCsvParseOptions
10
+ ): Promise<unknown[]>;
11
+
12
+ export function generateCsvResponse(
13
+ data: unknown[] | Record<string, unknown>,
14
+ filename?: string,
15
+ options?: JsonToCsvOptions
16
+ ): Response;