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,77 +0,0 @@
1
- const { Injectable, UseInterceptors } = require('@nestjs/common');
2
- const { map } = require('rxjs/operators');
3
- const jtcsv = require('jtcsv');
4
-
5
- function normalizeFilename(filename) {
6
- if (!filename || typeof filename !== 'string') {
7
- return 'export.csv';
8
- }
9
- return filename.includes('.') ? filename : `${filename}.csv`;
10
- }
11
-
12
- function createCsvParserInterceptor(options = {}) {
13
- class CsvParserInterceptorImpl {
14
- intercept(context, next) {
15
- const req = context.switchToHttp().getRequest();
16
- const body = req && req.body;
17
-
18
- if (typeof body === 'string' || Buffer.isBuffer(body)) {
19
- const csv = Buffer.isBuffer(body) ? body.toString('utf8') : body;
20
- req.body = jtcsv.csvToJson(csv, options);
21
- }
22
-
23
- return next.handle();
24
- }
25
- }
26
-
27
- Injectable()(CsvParserInterceptorImpl);
28
- return CsvParserInterceptorImpl;
29
- }
30
-
31
- function createCsvDownloadInterceptor(options = {}) {
32
- class CsvDownloadInterceptorImpl {
33
- intercept(context, next) {
34
- const res = context.switchToHttp().getResponse();
35
- const filename = normalizeFilename(options.filename);
36
- const csvOptions = { ...options };
37
- delete csvOptions.filename;
38
-
39
- return next.handle().pipe(
40
- map(data => {
41
- const rows = Array.isArray(data) ? data : [data];
42
- const csv = jtcsv.jsonToCsv(rows, csvOptions);
43
-
44
- if (res && typeof res.setHeader === 'function') {
45
- res.setHeader('Content-Type', 'text/csv; charset=utf-8');
46
- res.setHeader(
47
- 'Content-Disposition',
48
- `attachment; filename="${filename}"`
49
- );
50
- }
51
-
52
- return csv;
53
- })
54
- );
55
- }
56
- }
57
-
58
- Injectable()(CsvDownloadInterceptorImpl);
59
- return CsvDownloadInterceptorImpl;
60
- }
61
-
62
- function CsvParserInterceptor(options = {}) {
63
- const Interceptor = createCsvParserInterceptor(options);
64
- return UseInterceptors(new Interceptor());
65
- }
66
-
67
- function CsvDownloadDecorator(options = {}) {
68
- const Interceptor = createCsvDownloadInterceptor(options);
69
- return UseInterceptors(new Interceptor());
70
- }
71
-
72
- module.exports = {
73
- CsvParserInterceptor,
74
- CsvDownloadDecorator,
75
- createCsvParserInterceptor,
76
- createCsvDownloadInterceptor
77
- };
@@ -1,37 +0,0 @@
1
- {
2
- "name": "@jtcsv/nestjs",
3
- "version": "1.0.0",
4
- "description": "NestJS interceptors and decorators for JTCSV",
5
- "main": "index.js",
6
- "types": "index.d.ts",
7
- "keywords": [
8
- "nestjs",
9
- "csv",
10
- "json",
11
- "converter",
12
- "jtcsv",
13
- "interceptor",
14
- "decorator"
15
- ],
16
- "author": "Ruslan Fomenko",
17
- "license": "MIT",
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/Linol-Hamelton/jtcsv.git",
21
- "directory": "plugins/nestjs"
22
- },
23
- "bugs": {
24
- "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
25
- },
26
- "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/nestjs#readme",
27
- "peerDependencies": {
28
- "@nestjs/common": "^9.0.0 || ^10.0.0",
29
- "jtcsv": "^2.1.3",
30
- "rxjs": "^7.0.0"
31
- },
32
- "files": [
33
- "index.js",
34
- "index.d.ts",
35
- "README.md"
36
- ]
37
- }
@@ -1,57 +0,0 @@
1
- # @jtcsv/nextjs
2
-
3
- Next.js helpers for JTCSV: API route handler, React hooks, and browser helpers.
4
-
5
- ## Install
6
- ```bash
7
- npm install @jtcsv/nextjs jtcsv
8
- ```
9
-
10
- ## API route
11
- ```javascript
12
- // pages/api/convert.js
13
- import handler from '@jtcsv/nextjs/route';
14
-
15
- export default handler;
16
- ```
17
-
18
- Query options handled by the route:
19
- - format: json|csv
20
- - delimiter
21
- - includeHeaders
22
- - parseNumbers
23
- - parseBooleans
24
- - useFastPath
25
- - preventCsvInjection
26
-
27
- ## React hook
28
- ```jsx
29
- 'use client';
30
- import { useJtcsv } from '@jtcsv/nextjs';
31
-
32
- export default function Converter() {
33
- const { convertCsvToJson, convertJsonToCsv, isLoading, error, result } = useJtcsv();
34
- return null;
35
- }
36
- ```
37
-
38
- ## Components and utilities
39
- ```javascript
40
- import {
41
- CsvFileUploader,
42
- downloadCsv,
43
- createJtcsvApiClient,
44
- JtcsvProvider,
45
- useJtcsvContext
46
- } from '@jtcsv/nextjs';
47
- ```
48
-
49
- ## Route helpers
50
- ```javascript
51
- import {
52
- csvToJsonHandler,
53
- jsonToCsvHandler,
54
- healthCheckHandler,
55
- createJtcsvApiEndpoint
56
- } from '@jtcsv/nextjs/route';
57
- ```
@@ -1,386 +0,0 @@
1
- /**
2
- * Пример React компонента для конвертации CSV/JSON
3
- * Использование в Next.js приложении
4
- */
5
-
6
- import React, { useState } from 'react';
7
- import { useJtcsv, CsvFileUploader, downloadCsv } from '../index';
8
-
9
- /**
10
- * Компонент для конвертации CSV ↔ JSON
11
- */
12
- export default function ConverterComponent() {
13
- const [input, setInput] = useState('');
14
- const [output, setOutput] = useState('');
15
- const [format, setFormat] = useState('csv'); // 'csv' или 'json'
16
- const [delimiter, setDelimiter] = useState(',');
17
-
18
- const {
19
- convertCsvToJson,
20
- convertJsonToCsv,
21
- isLoading,
22
- error,
23
- stats
24
- } = useJtcsv({
25
- delimiter,
26
- parseNumbers: true,
27
- parseBooleans: true,
28
- preventCsvInjection: true
29
- });
30
-
31
- const handleConvert = async () => {
32
- if (!input.trim()) return;
33
-
34
- try {
35
- if (format === 'csv') {
36
- // Конвертируем CSV в JSON
37
- const result = await convertCsvToJson(input);
38
- setOutput(JSON.stringify(result, null, 2));
39
- } else {
40
- // Конвертируем JSON в CSV
41
- const json = JSON.parse(input);
42
- const result = await convertJsonToCsv(json);
43
- setOutput(result);
44
- }
45
- } catch (err) {
46
- setOutput(`Error: ${err.message}`);
47
- }
48
- };
49
-
50
- const handleFileUpload = (result, fileStats) => {
51
- setInput(JSON.stringify(result, null, 2));
52
- setFormat('json');
53
-
54
- console.log('File converted:', fileStats);
55
- };
56
-
57
- const handleDownload = async () => {
58
- if (!output) return;
59
-
60
- try {
61
- if (format === 'csv') {
62
- // Скачиваем как CSV
63
- const json = JSON.parse(input);
64
- await downloadCsv(json, 'converted.csv', { delimiter });
65
- } else {
66
- // Скачиваем как JSON
67
- const blob = new Blob([output], { type: 'application/json' });
68
- const url = URL.createObjectURL(blob);
69
- const link = document.createElement('a');
70
- link.href = url;
71
- link.download = 'converted.json';
72
- link.click();
73
- URL.revokeObjectURL(url);
74
- }
75
- } catch (err) {
76
- console.error('Download error:', err);
77
- }
78
- };
79
-
80
- const handleExample = () => {
81
- if (format === 'csv') {
82
- setInput('name,email,age\nJohn Doe,john@example.com,30\nJane Smith,jane@example.com,25');
83
- } else {
84
- setInput(JSON.stringify([
85
- { name: 'John Doe', email: 'john@example.com', age: 30 },
86
- { name: 'Jane Smith', email: 'jane@example.com', age: 25 }
87
- ], null, 2));
88
- }
89
- };
90
-
91
- const handleClear = () => {
92
- setInput('');
93
- setOutput('');
94
- };
95
-
96
- return (
97
- <div style={styles.container}>
98
- <h1 style={styles.title}>🔄 JTCSV Converter</h1>
99
-
100
- <div style={styles.controls}>
101
- <div style={styles.formatSelector}>
102
- <label>
103
- <input
104
- type="radio"
105
- value="csv"
106
- checked={format === 'csv'}
107
- onChange={(e) => setFormat(e.target.value)}
108
- />
109
- CSV → JSON
110
- </label>
111
- <label>
112
- <input
113
- type="radio"
114
- value="json"
115
- checked={format === 'json'}
116
- onChange={(e) => setFormat(e.target.value)}
117
- />
118
- JSON → CSV
119
- </label>
120
- </div>
121
-
122
- <div style={styles.delimiterSelector}>
123
- <label>
124
- Разделитель:
125
- <select
126
- value={delimiter}
127
- onChange={(e) => setDelimiter(e.target.value)}
128
- style={styles.select}
129
- >
130
- <option value=",">Запятая (,)</option>
131
- <option value=";">Точка с запятой (;)</option>
132
- <option value="\t">Табуляция (\t)</option>
133
- <option value="|">Вертикальная черта (|)</option>
134
- </select>
135
- </label>
136
- </div>
137
- </div>
138
-
139
- <div style={styles.inputSection}>
140
- <div style={styles.inputHeader}>
141
- <h3 style={styles.sectionTitle}>
142
- {format === 'csv' ? 'CSV Input' : 'JSON Input'}
143
- </h3>
144
- <div style={styles.inputActions}>
145
- <CsvFileUploader
146
- onConvert={handleFileUpload}
147
- options={{ delimiter }}
148
- >
149
- <button style={styles.buttonSecondary}>📁 Upload CSV</button>
150
- </CsvFileUploader>
151
- <button
152
- onClick={handleExample}
153
- style={styles.buttonSecondary}
154
- >
155
- 📋 Example
156
- </button>
157
- <button
158
- onClick={handleClear}
159
- style={styles.buttonSecondary}
160
- >
161
- 🗑️ Clear
162
- </button>
163
- </div>
164
- </div>
165
-
166
- <textarea
167
- value={input}
168
- onChange={(e) => setInput(e.target.value)}
169
- placeholder={format === 'csv'
170
- ? 'Введите CSV данные...\nПример:\nname,email,age\nJohn,john@example.com,30'
171
- : 'Введите JSON данные...\nПример:\n[{"name":"John","age":30}]'
172
- }
173
- style={styles.textarea}
174
- rows={10}
175
- />
176
- </div>
177
-
178
- <div style={styles.convertButtonContainer}>
179
- <button
180
- onClick={handleConvert}
181
- disabled={isLoading || !input.trim()}
182
- style={{
183
- ...styles.buttonPrimary,
184
- opacity: isLoading || !input.trim() ? 0.6 : 1,
185
- cursor: isLoading || !input.trim() ? 'not-allowed' : 'pointer'
186
- }}
187
- >
188
- {isLoading ? '🔄 Converting...' : '🚀 Convert'}
189
- </button>
190
-
191
- {stats && (
192
- <div style={styles.stats}>
193
- <span>⏱️ {stats.processingTime}ms</span>
194
- <span>📊 {stats.rows || stats.size} {stats.rows ? 'rows' : 'chars'}</span>
195
- </div>
196
- )}
197
- </div>
198
-
199
- {error && (
200
- <div style={styles.error}>
201
- ❌ Error: {error}
202
- </div>
203
- )}
204
-
205
- <div style={styles.outputSection}>
206
- <div style={styles.outputHeader}>
207
- <h3 style={styles.sectionTitle}>
208
- {format === 'csv' ? 'JSON Output' : 'CSV Output'}
209
- </h3>
210
- <div style={styles.outputActions}>
211
- <button
212
- onClick={handleDownload}
213
- disabled={!output}
214
- style={styles.buttonSecondary}
215
- >
216
- ⬇️ Download
217
- </button>
218
- <button
219
- onClick={() => navigator.clipboard.writeText(output)}
220
- disabled={!output}
221
- style={styles.buttonSecondary}
222
- >
223
- 📋 Copy
224
- </button>
225
- </div>
226
- </div>
227
-
228
- <pre style={styles.output}>
229
- {output || 'Результат появится здесь...'}
230
- </pre>
231
- </div>
232
-
233
- <div style={styles.info}>
234
- <p>💡 <strong>Подсказки:</strong></p>
235
- <ul style={styles.tipsList}>
236
- <li>Используйте кнопку "Example" для быстрого заполнения</li>
237
- <li>Загружайте CSV файлы через кнопку "Upload CSV"</li>
238
- <li>Выберите разделитель соответствующий вашим данным</li>
239
- <li>Скачивайте результат в нужном формате</li>
240
- </ul>
241
- </div>
242
- </div>
243
- );
244
- }
245
-
246
- const styles = {
247
- container: {
248
- maxWidth: '1200px',
249
- margin: '0 auto',
250
- padding: '20px',
251
- fontFamily: 'system-ui, -apple-system, sans-serif'
252
- },
253
- title: {
254
- color: '#333',
255
- textAlign: 'center',
256
- marginBottom: '30px'
257
- },
258
- controls: {
259
- display: 'flex',
260
- justifyContent: 'space-between',
261
- alignItems: 'center',
262
- marginBottom: '20px',
263
- flexWrap: 'wrap',
264
- gap: '20px'
265
- },
266
- formatSelector: {
267
- display: 'flex',
268
- gap: '20px'
269
- },
270
- delimiterSelector: {
271
- display: 'flex',
272
- alignItems: 'center',
273
- gap: '10px'
274
- },
275
- select: {
276
- padding: '5px 10px',
277
- marginLeft: '10px',
278
- borderRadius: '4px',
279
- border: '1px solid #ccc'
280
- },
281
- inputSection: {
282
- marginBottom: '20px'
283
- },
284
- inputHeader: {
285
- display: 'flex',
286
- justifyContent: 'space-between',
287
- alignItems: 'center',
288
- marginBottom: '10px'
289
- },
290
- inputActions: {
291
- display: 'flex',
292
- gap: '10px'
293
- },
294
- sectionTitle: {
295
- margin: '0',
296
- color: '#555'
297
- },
298
- textarea: {
299
- width: '100%',
300
- padding: '15px',
301
- border: '1px solid #ddd',
302
- borderRadius: '8px',
303
- fontFamily: 'monospace',
304
- fontSize: '14px',
305
- resize: 'vertical',
306
- boxSizing: 'border-box'
307
- },
308
- convertButtonContainer: {
309
- display: 'flex',
310
- flexDirection: 'column',
311
- alignItems: 'center',
312
- gap: '10px',
313
- margin: '20px 0'
314
- },
315
- buttonPrimary: {
316
- padding: '12px 30px',
317
- background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
318
- color: 'white',
319
- border: 'none',
320
- borderRadius: '25px',
321
- fontSize: '16px',
322
- fontWeight: 'bold',
323
- cursor: 'pointer',
324
- transition: 'transform 0.2s'
325
- },
326
- buttonSecondary: {
327
- padding: '8px 16px',
328
- background: '#f0f0f0',
329
- color: '#333',
330
- border: '1px solid #ddd',
331
- borderRadius: '4px',
332
- cursor: 'pointer',
333
- transition: 'background 0.2s'
334
- },
335
- stats: {
336
- display: 'flex',
337
- gap: '20px',
338
- color: '#666',
339
- fontSize: '14px'
340
- },
341
- error: {
342
- padding: '15px',
343
- background: '#fee',
344
- border: '1px solid #f99',
345
- borderRadius: '8px',
346
- color: '#c00',
347
- marginBottom: '20px'
348
- },
349
- outputSection: {
350
- marginTop: '20px'
351
- },
352
- outputHeader: {
353
- display: 'flex',
354
- justifyContent: 'space-between',
355
- alignItems: 'center',
356
- marginBottom: '10px'
357
- },
358
- outputActions: {
359
- display: 'flex',
360
- gap: '10px'
361
- },
362
- output: {
363
- padding: '15px',
364
- background: '#f8f8f8',
365
- border: '1px solid #ddd',
366
- borderRadius: '8px',
367
- minHeight: '200px',
368
- overflow: 'auto',
369
- whiteSpace: 'pre-wrap',
370
- wordBreak: 'break-all',
371
- fontFamily: 'monospace',
372
- fontSize: '14px'
373
- },
374
- info: {
375
- marginTop: '30px',
376
- padding: '20px',
377
- background: '#f0f8ff',
378
- border: '1px solid #cce5ff',
379
- borderRadius: '8px'
380
- },
381
- tipsList: {
382
- margin: '10px 0 0 20px',
383
- color: '#555'
384
- }
385
- };
386
-
@@ -1,69 +0,0 @@
1
- /**
2
- * Пример API route для Next.js
3
- * Сохраните этот файл как pages/api/convert.js
4
- *
5
- * @example
6
- * // Запросы к API:
7
- * // POST /api/convert с JSON телом → получите CSV
8
- * // POST /api/convert с CSV телом → получите JSON
9
- * // GET /api/convert/health → проверка состояния
10
- */
11
-
12
- import {
13
- handler as jtcsvHandler,
14
- csvToJsonHandler,
15
- jsonToCsvHandler,
16
- healthCheckHandler
17
- } from '../../route';
18
-
19
- // Основной endpoint для автоматической конвертации
20
- export default jtcsvHandler;
21
-
22
- // Специализированные endpoints
23
- export const config = {
24
- api: {
25
- bodyParser: {
26
- sizeLimit: '50mb'
27
- }
28
- }
29
- };
30
-
31
- // Альтернативная реализация с отдельными путями
32
- // export default async function handler(req, res) {
33
- // const { path } = req.query;
34
- //
35
- // switch (path) {
36
- // case 'csv-to-json':
37
- // return csvToJsonHandler(req, res);
38
- // case 'json-to-csv':
39
- // return jsonToCsvHandler(req, res);
40
- // case 'health':
41
- // return healthCheckHandler(req, res);
42
- // default:
43
- // return jtcsvHandler(req, res);
44
- // }
45
- // }
46
-
47
- /**
48
- * Пример использования с кастомной логикой
49
- *
50
- * export default async function handler(req, res) {
51
- * // Добавляем логирование
52
- * console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
53
- *
54
- * // Проверяем аутентификацию
55
- * const apiKey = req.headers['x-api-key'];
56
- * if (!apiKey || apiKey !== process.env.API_KEY) {
57
- * return res.status(401).json({ error: 'Unauthorized' });
58
- * }
59
- *
60
- * // Ограничение по частоте запросов
61
- * const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
62
- * // ... rate limiting logic
63
- *
64
- * // Вызываем основной обработчик
65
- * return jtcsvHandler(req, res);
66
- * }
67
- */
68
-
69
-