jtcsv 2.2.7 → 3.0.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.
- package/README.md +31 -1
- package/bin/jtcsv.js +891 -821
- package/bin/jtcsv.ts +2534 -0
- package/csv-to-json.js +168 -145
- package/dist/jtcsv-core.cjs.js +1407 -0
- package/dist/jtcsv-core.cjs.js.map +1 -0
- package/dist/jtcsv-core.esm.js +1379 -0
- package/dist/jtcsv-core.esm.js.map +1 -0
- package/dist/jtcsv-core.umd.js +1413 -0
- package/dist/jtcsv-core.umd.js.map +1 -0
- package/dist/jtcsv-full.cjs.js +1912 -0
- package/dist/jtcsv-full.cjs.js.map +1 -0
- package/dist/jtcsv-full.esm.js +1880 -0
- package/dist/jtcsv-full.esm.js.map +1 -0
- package/dist/jtcsv-full.umd.js +1918 -0
- package/dist/jtcsv-full.umd.js.map +1 -0
- package/dist/jtcsv-workers.esm.js +759 -0
- package/dist/jtcsv-workers.esm.js.map +1 -0
- package/dist/jtcsv-workers.umd.js +773 -0
- package/dist/jtcsv-workers.umd.js.map +1 -0
- package/dist/jtcsv.cjs.js +61 -19
- package/dist/jtcsv.cjs.js.map +1 -1
- package/dist/jtcsv.esm.js +61 -19
- package/dist/jtcsv.esm.js.map +1 -1
- package/dist/jtcsv.umd.js +61 -19
- package/dist/jtcsv.umd.js.map +1 -1
- package/errors.js +188 -2
- package/examples/advanced/conditional-transformations.js +446 -0
- package/examples/advanced/conditional-transformations.ts +446 -0
- package/examples/advanced/csv-parser.worker.js +89 -0
- package/examples/advanced/csv-parser.worker.ts +89 -0
- package/examples/advanced/nested-objects-example.js +306 -0
- package/examples/advanced/nested-objects-example.ts +306 -0
- package/examples/advanced/performance-optimization.js +504 -0
- package/examples/advanced/performance-optimization.ts +504 -0
- package/examples/advanced/run-demo-server.js +116 -0
- package/examples/advanced/run-demo-server.ts +116 -0
- package/examples/advanced/web-worker-usage.html +874 -0
- package/examples/async-multithreaded-example.ts +335 -0
- package/examples/cli-advanced-usage.md +288 -0
- package/examples/cli-batch-processing.ts +38 -0
- package/examples/cli-tool.js +0 -3
- package/examples/cli-tool.ts +183 -0
- package/examples/error-handling.js +21 -7
- package/examples/error-handling.ts +356 -0
- package/examples/express-api.js +0 -3
- package/examples/express-api.ts +164 -0
- package/examples/large-dataset-example.js +0 -3
- package/examples/large-dataset-example.ts +204 -0
- package/examples/ndjson-processing.js +1 -1
- package/examples/ndjson-processing.ts +456 -0
- package/examples/plugin-excel-exporter.js +3 -4
- package/examples/plugin-excel-exporter.ts +406 -0
- package/examples/react-integration.tsx +637 -0
- package/examples/schema-validation.ts +640 -0
- package/examples/simple-usage.js +254 -254
- package/examples/simple-usage.ts +194 -0
- package/examples/streaming-example.js +4 -5
- package/examples/streaming-example.ts +419 -0
- package/examples/web-workers-advanced.ts +28 -0
- package/index.d.ts +1 -3
- package/index.js +15 -1
- package/json-save.js +9 -3
- package/json-to-csv.js +168 -21
- package/package.json +69 -10
- package/plugins/express-middleware/README.md +21 -2
- package/plugins/express-middleware/example.js +3 -4
- package/plugins/express-middleware/example.ts +135 -0
- package/plugins/express-middleware/index.d.ts +1 -1
- package/plugins/express-middleware/index.js +270 -118
- package/plugins/express-middleware/index.ts +557 -0
- package/plugins/fastify-plugin/index.js +2 -4
- package/plugins/fastify-plugin/index.ts +443 -0
- package/plugins/hono/index.ts +226 -0
- package/plugins/nestjs/index.ts +201 -0
- package/plugins/nextjs-api/examples/ConverterComponent.tsx +386 -0
- package/plugins/nextjs-api/examples/api-convert.js +0 -2
- package/plugins/nextjs-api/examples/api-convert.ts +67 -0
- package/plugins/nextjs-api/index.tsx +339 -0
- package/plugins/nextjs-api/route.js +2 -3
- package/plugins/nextjs-api/route.ts +370 -0
- package/plugins/nuxt/index.ts +94 -0
- package/plugins/nuxt/runtime/composables/useJtcsv.ts +100 -0
- package/plugins/nuxt/runtime/plugin.ts +71 -0
- package/plugins/remix/index.js +1 -1
- package/plugins/remix/index.ts +260 -0
- package/plugins/sveltekit/index.js +1 -1
- package/plugins/sveltekit/index.ts +301 -0
- package/plugins/trpc/index.ts +267 -0
- package/src/browser/browser-functions.ts +402 -0
- package/src/browser/core.js +92 -0
- package/src/browser/core.ts +152 -0
- package/src/browser/csv-to-json-browser.d.ts +3 -0
- package/src/browser/csv-to-json-browser.js +36 -14
- package/src/browser/csv-to-json-browser.ts +264 -0
- package/src/browser/errors-browser.ts +303 -0
- package/src/browser/extensions/plugins.js +92 -0
- package/src/browser/extensions/plugins.ts +93 -0
- package/src/browser/extensions/workers.js +39 -0
- package/src/browser/extensions/workers.ts +39 -0
- package/src/browser/globals.d.ts +5 -0
- package/src/browser/index.ts +192 -0
- package/src/browser/json-to-csv-browser.d.ts +3 -0
- package/src/browser/json-to-csv-browser.js +13 -3
- package/src/browser/json-to-csv-browser.ts +262 -0
- package/src/browser/streams.js +12 -2
- package/src/browser/streams.ts +336 -0
- package/src/browser/workers/csv-parser.worker.ts +377 -0
- package/src/browser/workers/worker-pool.ts +548 -0
- package/src/core/delimiter-cache.js +22 -8
- package/src/core/delimiter-cache.ts +310 -0
- package/src/core/node-optimizations.ts +449 -0
- package/src/core/plugin-system.js +29 -11
- package/src/core/plugin-system.ts +400 -0
- package/src/core/transform-hooks.ts +558 -0
- package/src/engines/fast-path-engine-new.ts +347 -0
- package/src/engines/fast-path-engine.ts +854 -0
- package/src/errors.ts +72 -0
- package/src/formats/ndjson-parser.ts +469 -0
- package/src/formats/tsv-parser.ts +334 -0
- package/src/index-with-plugins.js +16 -9
- package/src/index-with-plugins.ts +395 -0
- package/src/types/index.ts +255 -0
- package/src/utils/bom-utils.js +259 -0
- package/src/utils/bom-utils.ts +373 -0
- package/src/utils/encoding-support.js +124 -0
- package/src/utils/encoding-support.ts +155 -0
- package/src/utils/schema-validator.js +19 -19
- package/src/utils/schema-validator.ts +819 -0
- package/src/utils/transform-loader.js +1 -1
- package/src/utils/transform-loader.ts +389 -0
- package/src/utils/zod-adapter.js +170 -0
- package/src/utils/zod-adapter.ts +280 -0
- package/src/web-server/index.js +10 -10
- package/src/web-server/index.ts +683 -0
- package/src/workers/csv-multithreaded.ts +310 -0
- package/src/workers/csv-parser.worker.ts +227 -0
- package/src/workers/worker-pool.ts +409 -0
- package/stream-csv-to-json.js +26 -8
- package/stream-json-to-csv.js +1 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js API Route plugin for jtcsv
|
|
3
|
+
* Provides API routes for CSV/JSON conversion in Next.js applications
|
|
4
|
+
* @module plugins/nextjs-api
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Note: Next.js types are optional - users need to install @types/next
|
|
8
|
+
// We use conditional imports to avoid breaking the build
|
|
9
|
+
type NextApiRequest = any;
|
|
10
|
+
type NextApiResponse = any;
|
|
11
|
+
|
|
12
|
+
import type { CsvToJsonOptions, JsonToCsvOptions } from '../../src/types';
|
|
13
|
+
import { csvToJson, jsonToCsv } from '../../index-core';
|
|
14
|
+
import { JtcsvError } from '../../errors';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Configuration options for the Next.js API plugin
|
|
18
|
+
*/
|
|
19
|
+
export interface NextJsApiOptions {
|
|
20
|
+
/** Maximum request body size in bytes (default: 10MB) */
|
|
21
|
+
maxBodySize?: number;
|
|
22
|
+
/** Allowed HTTP methods (default: ['POST']) */
|
|
23
|
+
allowedMethods?: string[];
|
|
24
|
+
/** Enable CORS headers (default: true) */
|
|
25
|
+
enableCors?: boolean;
|
|
26
|
+
/** Custom error handler */
|
|
27
|
+
onError?: (error: Error, req: NextApiRequest, res: NextApiResponse) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Default configuration for the Next.js API plugin
|
|
32
|
+
*/
|
|
33
|
+
const DEFAULT_OPTIONS: NextJsApiOptions = {
|
|
34
|
+
maxBodySize: 10 * 1024 * 1024, // 10MB
|
|
35
|
+
allowedMethods: ['POST'],
|
|
36
|
+
enableCors: true,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Creates a Next.js API route handler for CSV to JSON conversion
|
|
41
|
+
* @param options - Plugin configuration options
|
|
42
|
+
* @returns Next.js API route handler
|
|
43
|
+
*/
|
|
44
|
+
export function createCsvToJsonApiHandler(options?: NextJsApiOptions) {
|
|
45
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
46
|
+
|
|
47
|
+
return async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
48
|
+
try {
|
|
49
|
+
// Set CORS headers if enabled
|
|
50
|
+
if (config.enableCors) {
|
|
51
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
52
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
|
53
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Handle OPTIONS request for CORS preflight
|
|
57
|
+
if (req.method === 'OPTIONS') {
|
|
58
|
+
return res.status(200).end();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Validate HTTP method
|
|
62
|
+
if (!config.allowedMethods?.includes(req.method || '')) {
|
|
63
|
+
return res.status(405).json({
|
|
64
|
+
error: 'Method Not Allowed',
|
|
65
|
+
message: `Only ${config.allowedMethods?.join(', ')} methods are allowed`,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Validate content type
|
|
70
|
+
const contentType = req.headers['content-type'] || '';
|
|
71
|
+
if (!contentType.includes('text/csv') && !contentType.includes('application/csv')) {
|
|
72
|
+
return res.status(400).json({
|
|
73
|
+
error: 'Invalid Content-Type',
|
|
74
|
+
message: 'Content-Type must be text/csv or application/csv',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Get request body
|
|
79
|
+
let csvData: string;
|
|
80
|
+
if (typeof req.body === 'string') {
|
|
81
|
+
csvData = req.body;
|
|
82
|
+
} else if (Buffer.isBuffer(req.body)) {
|
|
83
|
+
csvData = req.body.toString('utf-8');
|
|
84
|
+
} else {
|
|
85
|
+
return res.status(400).json({
|
|
86
|
+
error: 'Invalid Request Body',
|
|
87
|
+
message: 'Request body must be a CSV string or buffer',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Validate body size
|
|
92
|
+
if (csvData.length > (config.maxBodySize || DEFAULT_OPTIONS.maxBodySize!)) {
|
|
93
|
+
return res.status(413).json({
|
|
94
|
+
error: 'Payload Too Large',
|
|
95
|
+
message: `Request body exceeds maximum size of ${config.maxBodySize} bytes`,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Parse query parameters for CSV options
|
|
100
|
+
const csvOptions: CsvToJsonOptions = {
|
|
101
|
+
delimiter: req.query.delimiter as string || ',',
|
|
102
|
+
hasHeaders: req.query.hasHeaders !== 'false',
|
|
103
|
+
trim: req.query.trim === 'true',
|
|
104
|
+
maxRows: req.query.maxRows ? parseInt(req.query.maxRows as string, 10) : undefined,
|
|
105
|
+
parseNumbers: req.query.parseNumbers === 'true',
|
|
106
|
+
parseBooleans: req.query.parseBooleans === 'true',
|
|
107
|
+
useFastPath: req.query.useFastPath !== 'false',
|
|
108
|
+
preventCsvInjection: req.query.preventCsvInjection !== 'false',
|
|
109
|
+
rfc4180Compliant: req.query.rfc4180Compliant !== 'false',
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Convert CSV to JSON
|
|
113
|
+
const result = await csvToJson(csvData, csvOptions);
|
|
114
|
+
|
|
115
|
+
// Return successful response
|
|
116
|
+
return res.status(200).json({
|
|
117
|
+
success: true,
|
|
118
|
+
data: result,
|
|
119
|
+
metadata: {
|
|
120
|
+
rowCount: Array.isArray(result) ? result.length : 0,
|
|
121
|
+
convertedAt: new Date().toISOString(),
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
} catch (error) {
|
|
126
|
+
// Handle errors
|
|
127
|
+
if (config.onError) {
|
|
128
|
+
config.onError(error as Error, req, res);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (error instanceof JtcsvError) {
|
|
132
|
+
return res.status(400).json({
|
|
133
|
+
error: error.name,
|
|
134
|
+
message: error.message,
|
|
135
|
+
code: error.code,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const err = error as Error;
|
|
140
|
+
return res.status(500).json({
|
|
141
|
+
error: 'Internal Server Error',
|
|
142
|
+
message: err.message || 'Unknown error occurred',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Creates a Next.js API route handler for JSON to CSV conversion
|
|
150
|
+
* @param options - Plugin configuration options
|
|
151
|
+
* @returns Next.js API route handler
|
|
152
|
+
*/
|
|
153
|
+
export function createJsonToCsvApiHandler(options?: NextJsApiOptions) {
|
|
154
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
155
|
+
|
|
156
|
+
return async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
157
|
+
try {
|
|
158
|
+
// Set CORS headers if enabled
|
|
159
|
+
if (config.enableCors) {
|
|
160
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
161
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
|
162
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Handle OPTIONS request for CORS preflight
|
|
166
|
+
if (req.method === 'OPTIONS') {
|
|
167
|
+
return res.status(200).end();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Validate HTTP method
|
|
171
|
+
if (!config.allowedMethods?.includes(req.method || '')) {
|
|
172
|
+
return res.status(405).json({
|
|
173
|
+
error: 'Method Not Allowed',
|
|
174
|
+
message: `Only ${config.allowedMethods?.join(', ')} methods are allowed`,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Validate content type
|
|
179
|
+
const contentType = req.headers['content-type'] || '';
|
|
180
|
+
if (!contentType.includes('application/json')) {
|
|
181
|
+
return res.status(400).json({
|
|
182
|
+
error: 'Invalid Content-Type',
|
|
183
|
+
message: 'Content-Type must be application/json',
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Get request body
|
|
188
|
+
let jsonData: any;
|
|
189
|
+
if (typeof req.body === 'string') {
|
|
190
|
+
try {
|
|
191
|
+
jsonData = JSON.parse(req.body);
|
|
192
|
+
} catch {
|
|
193
|
+
return res.status(400).json({
|
|
194
|
+
error: 'Invalid JSON',
|
|
195
|
+
message: 'Request body must be valid JSON',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
} else if (typeof req.body === 'object' && req.body !== null) {
|
|
199
|
+
jsonData = req.body;
|
|
200
|
+
} else {
|
|
201
|
+
return res.status(400).json({
|
|
202
|
+
error: 'Invalid Request Body',
|
|
203
|
+
message: 'Request body must be JSON',
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Validate body size
|
|
208
|
+
const bodySize = JSON.stringify(jsonData).length;
|
|
209
|
+
if (bodySize > (config.maxBodySize || DEFAULT_OPTIONS.maxBodySize!)) {
|
|
210
|
+
return res.status(413).json({
|
|
211
|
+
error: 'Payload Too Large',
|
|
212
|
+
message: `Request body exceeds maximum size of ${config.maxBodySize} bytes`,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Parse query parameters for CSV options
|
|
217
|
+
const csvOptions: JsonToCsvOptions = {
|
|
218
|
+
delimiter: req.query.delimiter as string || ',',
|
|
219
|
+
includeHeaders: req.query.includeHeaders !== 'false',
|
|
220
|
+
preventCsvInjection: req.query.preventCsvInjection !== 'false',
|
|
221
|
+
rfc4180Compliant: req.query.rfc4180Compliant !== 'false',
|
|
222
|
+
flatten: req.query.flatten === 'true',
|
|
223
|
+
flattenSeparator: req.query.flattenSeparator as string || '.',
|
|
224
|
+
flattenMaxDepth: req.query.flattenMaxDepth ? parseInt(req.query.flattenMaxDepth as string, 10) : undefined,
|
|
225
|
+
arrayHandling: req.query.arrayHandling as 'stringify' | 'join' | 'expand' || 'stringify',
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// Convert JSON to CSV
|
|
229
|
+
const result = await jsonToCsv(jsonData, csvOptions);
|
|
230
|
+
|
|
231
|
+
// Return successful response
|
|
232
|
+
res.setHeader('Content-Type', 'text/csv');
|
|
233
|
+
res.setHeader('Content-Disposition', 'attachment; filename="converted.csv"');
|
|
234
|
+
|
|
235
|
+
return res.status(200).send(result);
|
|
236
|
+
|
|
237
|
+
} catch (error) {
|
|
238
|
+
// Handle errors
|
|
239
|
+
if (config.onError) {
|
|
240
|
+
config.onError(error as Error, req, res);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (error instanceof JtcsvError) {
|
|
244
|
+
return res.status(400).json({
|
|
245
|
+
error: error.name,
|
|
246
|
+
message: error.message,
|
|
247
|
+
code: error.code,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const err = error as Error;
|
|
252
|
+
return res.status(500).json({
|
|
253
|
+
error: 'Internal Server Error',
|
|
254
|
+
message: err.message || 'Unknown error occurred',
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Creates a Next.js API route handler for bidirectional conversion
|
|
262
|
+
* @param options - Plugin configuration options
|
|
263
|
+
* @returns Next.js API route handler that can handle both CSV→JSON and JSON→CSV
|
|
264
|
+
*/
|
|
265
|
+
export function createBidirectionalApiHandler(options?: NextJsApiOptions) {
|
|
266
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
267
|
+
|
|
268
|
+
return async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
269
|
+
try {
|
|
270
|
+
// Set CORS headers if enabled
|
|
271
|
+
if (config.enableCors) {
|
|
272
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
273
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
|
274
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Handle OPTIONS request for CORS preflight
|
|
278
|
+
if (req.method === 'OPTIONS') {
|
|
279
|
+
return res.status(200).end();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Validate HTTP method
|
|
283
|
+
if (!config.allowedMethods?.includes(req.method || '')) {
|
|
284
|
+
return res.status(405).json({
|
|
285
|
+
error: 'Method Not Allowed',
|
|
286
|
+
message: `Only ${config.allowedMethods?.join(', ')} methods are allowed`,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Determine conversion direction from query parameter or content type
|
|
291
|
+
const direction = req.query.direction as string ||
|
|
292
|
+
(req.headers['content-type']?.includes('text/csv') ? 'csvToJson' : 'jsonToCsv');
|
|
293
|
+
|
|
294
|
+
if (direction === 'csvToJson') {
|
|
295
|
+
// Use CSV to JSON handler
|
|
296
|
+
const csvHandler = createCsvToJsonApiHandler(config);
|
|
297
|
+
return csvHandler(req, res);
|
|
298
|
+
} else if (direction === 'jsonToCsv') {
|
|
299
|
+
// Use JSON to CSV handler
|
|
300
|
+
const jsonHandler = createJsonToCsvApiHandler(config);
|
|
301
|
+
return jsonHandler(req, res);
|
|
302
|
+
} else {
|
|
303
|
+
return res.status(400).json({
|
|
304
|
+
error: 'Invalid Direction',
|
|
305
|
+
message: 'Direction must be either "csvToJson" or "jsonToCsv"',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
} catch (error) {
|
|
310
|
+
// Handle errors
|
|
311
|
+
if (config.onError) {
|
|
312
|
+
config.onError(error as Error, req, res);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return res.status(500).json({
|
|
316
|
+
error: 'Internal Server Error',
|
|
317
|
+
message: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Example Next.js API route implementation
|
|
325
|
+
* Usage in pages/api/convert.ts:
|
|
326
|
+
*
|
|
327
|
+
* import { createBidirectionalApiHandler } from '@jtcsv/nextjs-api';
|
|
328
|
+
*
|
|
329
|
+
* export default createBidirectionalApiHandler({
|
|
330
|
+
* maxBodySize: 5 * 1024 * 1024, // 5MB
|
|
331
|
+
* allowedMethods: ['POST', 'GET'],
|
|
332
|
+
* });
|
|
333
|
+
*/
|
|
334
|
+
|
|
335
|
+
export default {
|
|
336
|
+
createCsvToJsonApiHandler,
|
|
337
|
+
createJsonToCsvApiHandler,
|
|
338
|
+
createBidirectionalApiHandler,
|
|
339
|
+
};
|
|
@@ -85,7 +85,7 @@ export default async function handler(req, res) {
|
|
|
85
85
|
} = req.query;
|
|
86
86
|
|
|
87
87
|
// Определяем желаемый формат вывода
|
|
88
|
-
|
|
88
|
+
const outputFormat = format || (acceptHeader.includes('text/csv') ? 'csv' : 'json');
|
|
89
89
|
|
|
90
90
|
// Определяем формат входных данных
|
|
91
91
|
let inputFormat = 'unknown';
|
|
@@ -122,7 +122,7 @@ export default async function handler(req, res) {
|
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
let result;
|
|
125
|
-
|
|
125
|
+
const stats = {
|
|
126
126
|
inputSize: 0,
|
|
127
127
|
outputSize: 0,
|
|
128
128
|
processingTime: 0,
|
|
@@ -368,4 +368,3 @@ export function createJtcsvApiEndpoint(options = {}) {
|
|
|
368
368
|
return handler(req, res);
|
|
369
369
|
};
|
|
370
370
|
}
|
|
371
|
-
|