jtcsv 2.1.3 → 2.2.2
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.
- package/LICENSE +1 -1
- package/README.md +60 -341
- package/bin/jtcsv.js +2462 -1372
- package/csv-to-json.js +35 -26
- package/dist/jtcsv.cjs.js +807 -133
- package/dist/jtcsv.cjs.js.map +1 -1
- package/dist/jtcsv.esm.js +800 -134
- package/dist/jtcsv.esm.js.map +1 -1
- package/dist/jtcsv.umd.js +807 -133
- package/dist/jtcsv.umd.js.map +1 -1
- package/errors.js +20 -0
- package/examples/browser-vanilla.html +37 -0
- package/examples/cli-batch-processing.js +38 -0
- package/examples/error-handling.js +324 -0
- package/examples/ndjson-processing.js +434 -0
- package/examples/react-integration.jsx +637 -0
- package/examples/schema-validation.js +640 -0
- package/examples/simple-usage.js +10 -7
- package/examples/typescript-example.ts +486 -0
- package/examples/web-workers-advanced.js +28 -0
- package/index.d.ts +2 -0
- package/json-save.js +2 -1
- package/json-to-csv.js +171 -131
- package/package.json +20 -4
- package/plugins/README.md +41 -467
- package/plugins/express-middleware/README.md +32 -274
- package/plugins/hono/README.md +16 -13
- package/plugins/nestjs/README.md +13 -11
- package/plugins/nextjs-api/README.md +28 -423
- package/plugins/nextjs-api/index.js +1 -2
- package/plugins/nextjs-api/route.js +1 -2
- package/plugins/nuxt/README.md +6 -7
- package/plugins/remix/README.md +9 -9
- package/plugins/sveltekit/README.md +8 -8
- package/plugins/trpc/README.md +8 -5
- package/src/browser/browser-functions.js +33 -3
- package/src/browser/csv-to-json-browser.js +269 -11
- package/src/browser/errors-browser.js +19 -1
- package/src/browser/index.js +39 -5
- package/src/browser/streams.js +393 -0
- package/src/browser/workers/csv-parser.worker.js +20 -2
- package/src/browser/workers/worker-pool.js +507 -447
- package/src/core/plugin-system.js +4 -0
- package/src/engines/fast-path-engine.js +31 -23
- package/src/errors.js +26 -0
- package/src/formats/ndjson-parser.js +54 -5
- package/src/formats/tsv-parser.js +4 -1
- package/src/utils/schema-validator.js +594 -0
- package/src/utils/transform-loader.js +205 -0
- package/src/web-server/index.js +683 -0
- package/stream-csv-to-json.js +16 -87
- package/stream-json-to-csv.js +18 -86
|
@@ -1,452 +1,57 @@
|
|
|
1
1
|
# @jtcsv/nextjs
|
|
2
2
|
|
|
3
|
-
Next.js
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
104
|
-
|
|
49
|
+
## Route helpers
|
|
105
50
|
```javascript
|
|
106
|
-
|
|
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
|
-
|
package/plugins/nuxt/README.md
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
# @jtcsv/nuxt
|
|
2
2
|
|
|
3
|
-
Nuxt module
|
|
3
|
+
Nuxt module that injects `jtcsv` into the Nuxt app and provides a `useJtcsv` composable.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
```bash
|
|
7
7
|
npm install @jtcsv/nuxt jtcsv
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Nuxt config
|
|
11
11
|
```typescript
|
|
12
12
|
export default defineNuxtConfig({
|
|
13
13
|
modules: ['@jtcsv/nuxt'],
|
|
14
|
-
jtcsv: {
|
|
15
|
-
autoimport: true
|
|
16
|
-
}
|
|
14
|
+
jtcsv: { autoimport: true }
|
|
17
15
|
});
|
|
18
16
|
```
|
|
19
17
|
|
|
20
18
|
## Usage
|
|
21
19
|
```vue
|
|
22
20
|
<script setup>
|
|
23
|
-
const
|
|
21
|
+
const jtcsv = useJtcsv();
|
|
22
|
+
const csv = jtcsv.jsonToCsv([{ id: 1 }]);
|
|
24
23
|
</script>
|
|
25
|
-
```
|
|
24
|
+
```
|
package/plugins/remix/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @jtcsv/remix
|
|
2
2
|
|
|
3
|
-
Remix helpers for
|
|
3
|
+
Remix helpers for CSV form uploads and CSV responses.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
```bash
|
|
@@ -8,19 +8,19 @@ npm install @jtcsv/remix jtcsv
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
|
-
```
|
|
12
|
-
import { parseFormData, generateCsvResponse } from 'jtcsv/remix';
|
|
11
|
+
```javascript
|
|
12
|
+
import { parseFormData, generateCsvResponse } from '@jtcsv/remix';
|
|
13
13
|
|
|
14
14
|
export async function action({ request }) {
|
|
15
|
-
const rows = await parseFormData(request, { delimiter: ',' });
|
|
16
|
-
return {
|
|
15
|
+
const rows = await parseFormData(request, { fieldName: 'file', delimiter: ',' });
|
|
16
|
+
return { rows };
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export async function loader() {
|
|
20
|
-
return generateCsvResponse([{ id: 1
|
|
20
|
+
return generateCsvResponse([{ id: 1 }], 'export.csv');
|
|
21
21
|
}
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
##
|
|
25
|
-
-
|
|
26
|
-
-
|
|
24
|
+
## Exports
|
|
25
|
+
- parseFormData
|
|
26
|
+
- generateCsvResponse
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @jtcsv/sveltekit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Helpers for parsing CSV requests and returning CSV responses in SvelteKit.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
```bash
|
|
@@ -8,21 +8,21 @@ npm install @jtcsv/sveltekit jtcsv
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
|
-
```
|
|
12
|
-
import { parseCsv, generateCsv } from 'jtcsv/sveltekit';
|
|
11
|
+
```javascript
|
|
12
|
+
import { parseCsv, generateCsv } from '@jtcsv/sveltekit';
|
|
13
13
|
|
|
14
14
|
export const actions = {
|
|
15
15
|
upload: async ({ request }) => {
|
|
16
16
|
const rows = await parseCsv(request, { delimiter: ',' });
|
|
17
|
-
return {
|
|
17
|
+
return { rows };
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
export async function GET() {
|
|
22
|
-
return generateCsv([{ id: 1
|
|
22
|
+
return generateCsv([{ id: 1 }], 'export.csv');
|
|
23
23
|
}
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
##
|
|
27
|
-
-
|
|
28
|
-
-
|
|
26
|
+
## Exports
|
|
27
|
+
- parseCsv
|
|
28
|
+
- generateCsv
|
package/plugins/trpc/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @jtcsv/trpc
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Middleware helper that parses CSV input for tRPC procedures.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
```bash
|
|
@@ -8,15 +8,18 @@ npm install @jtcsv/trpc jtcsv
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
|
-
```
|
|
11
|
+
```javascript
|
|
12
12
|
import { initTRPC } from '@trpc/server';
|
|
13
13
|
import { z } from 'zod';
|
|
14
|
-
import { createCsvProcedure } from 'jtcsv/trpc';
|
|
14
|
+
import { createCsvProcedure } from '@jtcsv/trpc';
|
|
15
15
|
|
|
16
16
|
const t = initTRPC.create();
|
|
17
17
|
|
|
18
18
|
export const router = t.router({
|
|
19
|
-
parseCsv: createCsvProcedure(t, z.string()
|
|
20
|
-
.mutation(async ({ input }) => ({
|
|
19
|
+
parseCsv: createCsvProcedure(t, z.string())
|
|
20
|
+
.mutation(async ({ input }) => ({ rows: input }))
|
|
21
21
|
});
|
|
22
22
|
```
|
|
23
|
+
|
|
24
|
+
## Exports
|
|
25
|
+
- createCsvProcedure
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// Функции, которые работают только в браузере
|
|
3
3
|
|
|
4
4
|
import { jsonToCsv } from './json-to-csv-browser.js';
|
|
5
|
-
import { csvToJson } from './csv-to-json-browser.js';
|
|
5
|
+
import { csvToJson, csvToJsonIterator } from './csv-to-json-browser.js';
|
|
6
|
+
import { csvToJsonStream, jsonToCsvStream, jsonToNdjsonStream } from './streams.js';
|
|
6
7
|
import { ValidationError } from './errors-browser.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -130,6 +131,29 @@ export async function parseCsvFile(file, options = {}) {
|
|
|
130
131
|
});
|
|
131
132
|
}
|
|
132
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Stream CSV file as async iterator without full buffering.
|
|
136
|
+
*
|
|
137
|
+
* @param {File} file - File selected from input
|
|
138
|
+
* @param {Object} [options] - csvToJson options
|
|
139
|
+
* @returns {AsyncGenerator<Object>} Async iterator of rows
|
|
140
|
+
*/
|
|
141
|
+
export function parseCsvFileStream(file, options = {}) {
|
|
142
|
+
if (typeof window === 'undefined') {
|
|
143
|
+
throw new ValidationError('parseCsvFileStream() is browser-only. Use readCsvAsJson() in Node.js');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!(file instanceof File)) {
|
|
147
|
+
throw new ValidationError('Input must be a File object');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!file.name.toLowerCase().endsWith('.csv')) {
|
|
151
|
+
throw new ValidationError('File must have .csv extension');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return csvToJsonIterator(file, options);
|
|
155
|
+
}
|
|
156
|
+
|
|
133
157
|
/**
|
|
134
158
|
* Создает CSV файл из JSON данных (альтернатива downloadAsCsv)
|
|
135
159
|
* Возвращает Blob вместо автоматического скачивания
|
|
@@ -183,7 +207,13 @@ if (typeof module !== 'undefined' && module.exports) {
|
|
|
183
207
|
module.exports = {
|
|
184
208
|
downloadAsCsv,
|
|
185
209
|
parseCsvFile,
|
|
210
|
+
parseCsvFileStream,
|
|
186
211
|
createCsvBlob,
|
|
187
|
-
parseCsvBlob
|
|
212
|
+
parseCsvBlob,
|
|
213
|
+
jsonToCsvStream,
|
|
214
|
+
jsonToNdjsonStream,
|
|
215
|
+
csvToJsonStream
|
|
188
216
|
};
|
|
189
|
-
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export { jsonToCsvStream, jsonToNdjsonStream, csvToJsonStream };
|