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.
- package/README.md +204 -115
- package/bin/jtcsv.ts +2612 -0
- package/browser.d.ts +142 -0
- package/dist/benchmark.js +446 -0
- package/dist/benchmark.js.map +1 -0
- package/dist/bin/jtcsv.js +1940 -0
- package/dist/bin/jtcsv.js.map +1 -0
- package/dist/csv-to-json.js +1262 -0
- package/dist/csv-to-json.js.map +1 -0
- package/dist/errors.js +291 -0
- package/dist/errors.js.map +1 -0
- package/dist/eslint.config.js +147 -0
- package/dist/eslint.config.js.map +1 -0
- package/dist/index-core.js +95 -0
- package/dist/index-core.js.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/json-save.js +229 -0
- package/dist/json-save.js.map +1 -0
- package/dist/json-to-csv.js +576 -0
- package/dist/json-to-csv.js.map +1 -0
- package/dist/jtcsv-core.cjs.js +1736 -0
- package/dist/jtcsv-core.cjs.js.map +1 -0
- package/dist/jtcsv-core.esm.js +1708 -0
- package/dist/jtcsv-core.esm.js.map +1 -0
- package/dist/jtcsv-core.umd.js +1742 -0
- package/dist/jtcsv-core.umd.js.map +1 -0
- package/dist/jtcsv-full.cjs.js +2241 -0
- package/dist/jtcsv-full.cjs.js.map +1 -0
- package/dist/jtcsv-full.esm.js +2209 -0
- package/dist/jtcsv-full.esm.js.map +1 -0
- package/dist/jtcsv-full.umd.js +2247 -0
- package/dist/jtcsv-full.umd.js.map +1 -0
- package/dist/jtcsv-workers.esm.js +768 -0
- package/dist/jtcsv-workers.esm.js.map +1 -0
- package/dist/jtcsv-workers.umd.js +782 -0
- package/dist/jtcsv-workers.umd.js.map +1 -0
- package/dist/jtcsv.cjs.js +1996 -2048
- package/dist/jtcsv.cjs.js.map +1 -1
- package/dist/jtcsv.esm.js +1992 -2048
- package/dist/jtcsv.esm.js.map +1 -1
- package/dist/jtcsv.umd.js +2157 -2209
- package/dist/jtcsv.umd.js.map +1 -1
- package/dist/plugins/express-middleware/index.js +350 -0
- package/dist/plugins/express-middleware/index.js.map +1 -0
- package/dist/plugins/fastify-plugin/index.js +315 -0
- package/dist/plugins/fastify-plugin/index.js.map +1 -0
- package/dist/plugins/hono/index.js +111 -0
- package/dist/plugins/hono/index.js.map +1 -0
- package/dist/plugins/nestjs/index.js +112 -0
- package/dist/plugins/nestjs/index.js.map +1 -0
- package/dist/plugins/nuxt/index.js +53 -0
- package/dist/plugins/nuxt/index.js.map +1 -0
- package/dist/plugins/remix/index.js +133 -0
- package/dist/plugins/remix/index.js.map +1 -0
- package/dist/plugins/sveltekit/index.js +155 -0
- package/dist/plugins/sveltekit/index.js.map +1 -0
- package/dist/plugins/trpc/index.js +136 -0
- package/dist/plugins/trpc/index.js.map +1 -0
- package/dist/run-demo.js +49 -0
- package/dist/run-demo.js.map +1 -0
- package/dist/src/browser/browser-functions.js +193 -0
- package/dist/src/browser/browser-functions.js.map +1 -0
- package/dist/src/browser/core.js +123 -0
- package/dist/src/browser/core.js.map +1 -0
- package/dist/src/browser/csv-to-json-browser.js +353 -0
- package/dist/src/browser/csv-to-json-browser.js.map +1 -0
- package/dist/src/browser/errors-browser.js +219 -0
- package/dist/src/browser/errors-browser.js.map +1 -0
- package/dist/src/browser/extensions/plugins.js +106 -0
- package/dist/src/browser/extensions/plugins.js.map +1 -0
- package/dist/src/browser/extensions/workers.js +66 -0
- package/dist/src/browser/extensions/workers.js.map +1 -0
- package/dist/src/browser/index.js +140 -0
- package/dist/src/browser/index.js.map +1 -0
- package/dist/src/browser/json-to-csv-browser.js +225 -0
- package/dist/src/browser/json-to-csv-browser.js.map +1 -0
- package/dist/src/browser/streams.js +340 -0
- package/dist/src/browser/streams.js.map +1 -0
- package/dist/src/browser/workers/csv-parser.worker.js +264 -0
- package/dist/src/browser/workers/csv-parser.worker.js.map +1 -0
- package/dist/src/browser/workers/worker-pool.js +338 -0
- package/dist/src/browser/workers/worker-pool.js.map +1 -0
- package/dist/src/core/delimiter-cache.js +196 -0
- package/dist/src/core/delimiter-cache.js.map +1 -0
- package/dist/src/core/node-optimizations.js +279 -0
- package/dist/src/core/node-optimizations.js.map +1 -0
- package/dist/src/core/plugin-system.js +399 -0
- package/dist/src/core/plugin-system.js.map +1 -0
- package/dist/src/core/transform-hooks.js +348 -0
- package/dist/src/core/transform-hooks.js.map +1 -0
- package/dist/src/engines/fast-path-engine-new.js +262 -0
- package/dist/src/engines/fast-path-engine-new.js.map +1 -0
- package/dist/src/engines/fast-path-engine.js +671 -0
- package/dist/src/engines/fast-path-engine.js.map +1 -0
- package/dist/src/errors.js +18 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/formats/ndjson-parser.js +332 -0
- package/dist/src/formats/ndjson-parser.js.map +1 -0
- package/dist/src/formats/tsv-parser.js +230 -0
- package/dist/src/formats/tsv-parser.js.map +1 -0
- package/dist/src/index-with-plugins.js +259 -0
- package/dist/src/index-with-plugins.js.map +1 -0
- package/dist/src/types/index.js +3 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/utils/bom-utils.js +267 -0
- package/dist/src/utils/bom-utils.js.map +1 -0
- package/dist/src/utils/encoding-support.js +77 -0
- package/dist/src/utils/encoding-support.js.map +1 -0
- package/dist/src/utils/schema-validator.js +609 -0
- package/dist/src/utils/schema-validator.js.map +1 -0
- package/dist/src/utils/transform-loader.js +281 -0
- package/dist/src/utils/transform-loader.js.map +1 -0
- package/dist/src/utils/validators.js +40 -0
- package/dist/src/utils/validators.js.map +1 -0
- package/dist/src/utils/zod-adapter.js +144 -0
- package/dist/src/utils/zod-adapter.js.map +1 -0
- package/dist/src/web-server/index.js +648 -0
- package/dist/src/web-server/index.js.map +1 -0
- package/dist/src/workers/csv-multithreaded.js +211 -0
- package/dist/src/workers/csv-multithreaded.js.map +1 -0
- package/dist/src/workers/csv-parser.worker.js +179 -0
- package/dist/src/workers/csv-parser.worker.js.map +1 -0
- package/dist/src/workers/worker-pool.js +228 -0
- package/dist/src/workers/worker-pool.js.map +1 -0
- package/dist/stream-csv-to-json.js +665 -0
- package/dist/stream-csv-to-json.js.map +1 -0
- package/dist/stream-json-to-csv.js +389 -0
- package/dist/stream-json-to-csv.js.map +1 -0
- package/examples/advanced/conditional-transformations.ts +446 -0
- package/examples/advanced/csv-parser.worker.ts +89 -0
- package/examples/advanced/nested-objects-example.ts +306 -0
- package/examples/advanced/performance-optimization.ts +504 -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 +290 -0
- package/examples/{cli-batch-processing.js ā cli-batch-processing.ts} +38 -38
- package/examples/{cli-tool.js ā cli-tool.ts} +5 -8
- package/examples/{error-handling.js ā error-handling.ts} +356 -324
- package/examples/{express-api.js ā express-api.ts} +161 -164
- package/examples/{large-dataset-example.js ā large-dataset-example.ts} +201 -182
- package/examples/{ndjson-processing.js ā ndjson-processing.ts} +456 -434
- package/examples/{plugin-excel-exporter.js ā plugin-excel-exporter.ts} +6 -7
- package/examples/react-integration.tsx +637 -0
- package/examples/{schema-validation.js ā schema-validation.ts} +2 -2
- package/examples/simple-usage.ts +194 -0
- package/examples/{streaming-example.js ā streaming-example.ts} +12 -12
- package/index.d.ts +187 -18
- package/package.json +75 -81
- package/plugins.d.ts +37 -0
- package/schema.d.ts +103 -0
- package/src/browser/browser-functions.ts +402 -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.ts +494 -0
- package/src/browser/{errors-browser.js ā errors-browser.ts} +305 -197
- package/src/browser/extensions/plugins.ts +93 -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.ts +338 -0
- package/src/browser/streams.ts +403 -0
- package/src/browser/workers/{csv-parser.worker.js ā csv-parser.worker.ts} +3 -3
- package/src/browser/workers/{worker-pool.js ā worker-pool.ts} +51 -30
- package/src/core/delimiter-cache.ts +320 -0
- package/src/core/{node-optimizations.js ā node-optimizations.ts} +448 -407
- package/src/core/plugin-system.ts +588 -0
- package/src/core/transform-hooks.ts +566 -0
- package/src/engines/{fast-path-engine-new.js ā fast-path-engine-new.ts} +11 -2
- package/src/engines/{fast-path-engine.js ā fast-path-engine.ts} +79 -53
- package/src/errors.ts +1 -0
- package/src/formats/{ndjson-parser.js ā ndjson-parser.ts} +24 -16
- package/src/formats/{tsv-parser.js ā tsv-parser.ts} +18 -17
- package/src/{index-with-plugins.js ā index-with-plugins.ts} +381 -357
- package/src/types/index.ts +275 -0
- package/src/utils/bom-utils.ts +373 -0
- package/src/utils/encoding-support.ts +155 -0
- package/src/utils/{schema-validator.js ā schema-validator.ts} +814 -589
- package/src/utils/transform-loader.ts +389 -0
- package/src/utils/validators.ts +35 -0
- package/src/utils/zod-adapter.ts +280 -0
- package/src/web-server/{index.js ā index.ts} +19 -19
- 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/bin/jtcsv.js +0 -2462
- package/csv-to-json.js +0 -688
- package/errors.js +0 -208
- package/examples/simple-usage.js +0 -282
- package/index.js +0 -68
- package/json-save.js +0 -254
- package/json-to-csv.js +0 -526
- package/plugins/README.md +0 -91
- package/plugins/express-middleware/README.md +0 -64
- package/plugins/express-middleware/example.js +0 -136
- package/plugins/express-middleware/index.d.ts +0 -114
- package/plugins/express-middleware/index.js +0 -360
- package/plugins/express-middleware/package.json +0 -52
- package/plugins/fastify-plugin/index.js +0 -406
- package/plugins/fastify-plugin/package.json +0 -55
- package/plugins/hono/README.md +0 -28
- package/plugins/hono/index.d.ts +0 -12
- package/plugins/hono/index.js +0 -36
- package/plugins/hono/package.json +0 -35
- package/plugins/nestjs/README.md +0 -35
- package/plugins/nestjs/index.d.ts +0 -25
- package/plugins/nestjs/index.js +0 -77
- package/plugins/nestjs/package.json +0 -37
- package/plugins/nextjs-api/README.md +0 -57
- package/plugins/nextjs-api/examples/ConverterComponent.jsx +0 -386
- package/plugins/nextjs-api/examples/api-convert.js +0 -69
- package/plugins/nextjs-api/index.js +0 -387
- package/plugins/nextjs-api/package.json +0 -63
- package/plugins/nextjs-api/route.js +0 -371
- package/plugins/nuxt/README.md +0 -24
- package/plugins/nuxt/index.js +0 -21
- package/plugins/nuxt/package.json +0 -35
- package/plugins/nuxt/runtime/composables/useJtcsv.js +0 -6
- package/plugins/nuxt/runtime/plugin.js +0 -6
- package/plugins/remix/README.md +0 -26
- package/plugins/remix/index.d.ts +0 -16
- package/plugins/remix/index.js +0 -62
- package/plugins/remix/package.json +0 -35
- package/plugins/sveltekit/README.md +0 -28
- package/plugins/sveltekit/index.d.ts +0 -17
- package/plugins/sveltekit/index.js +0 -54
- package/plugins/sveltekit/package.json +0 -33
- package/plugins/trpc/README.md +0 -25
- package/plugins/trpc/index.d.ts +0 -7
- package/plugins/trpc/index.js +0 -32
- package/plugins/trpc/package.json +0 -34
- package/src/browser/browser-functions.js +0 -219
- package/src/browser/csv-to-json-browser.js +0 -700
- package/src/browser/index.js +0 -113
- package/src/browser/json-to-csv-browser.js +0 -309
- package/src/browser/streams.js +0 -393
- package/src/core/delimiter-cache.js +0 -186
- package/src/core/plugin-system.js +0 -476
- package/src/core/transform-hooks.js +0 -350
- package/src/errors.js +0 -26
- package/src/utils/transform-loader.js +0 -205
- package/stream-csv-to-json.js +0 -542
- package/stream-json-to-csv.js +0 -464
- /package/examples/{web-workers-advanced.js ā web-workers-advanced.ts} +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useJtcsv = useJtcsv;
|
|
4
|
+
exports.useJtcsvAsync = useJtcsvAsync;
|
|
5
|
+
exports.default = defineNuxtPlugin((nuxtApp, options = {}) => {
|
|
6
|
+
const { async = true, workers = false } = options;
|
|
7
|
+
const jtcsv = {
|
|
8
|
+
csvToJson: (csv, opts) => {
|
|
9
|
+
return require('jtcsv').csvToJson(csv, opts);
|
|
10
|
+
},
|
|
11
|
+
jsonToCsv: (data, opts) => {
|
|
12
|
+
return require('jtcsv').jsonToCsv(data, opts);
|
|
13
|
+
},
|
|
14
|
+
...(async ? {
|
|
15
|
+
csvToJsonAsync: async (csv, opts) => {
|
|
16
|
+
const { csvToJson } = require('jtcsv');
|
|
17
|
+
return csvToJson(csv, opts);
|
|
18
|
+
},
|
|
19
|
+
jsonToCsvAsync: async (data, opts) => {
|
|
20
|
+
const { jsonToCsv } = require('jtcsv');
|
|
21
|
+
return jsonToCsv(data, opts);
|
|
22
|
+
}
|
|
23
|
+
} : {}),
|
|
24
|
+
...(workers ? {
|
|
25
|
+
createWorkerPool: (size) => {
|
|
26
|
+
const { WorkerPool } = require('../../src/workers/worker-pool');
|
|
27
|
+
return new WorkerPool(size);
|
|
28
|
+
}
|
|
29
|
+
} : {})
|
|
30
|
+
};
|
|
31
|
+
nuxtApp.provide('jtcsv', jtcsv);
|
|
32
|
+
nuxtApp.provide('useJtcsv', () => jtcsv);
|
|
33
|
+
});
|
|
34
|
+
function useJtcsv() {
|
|
35
|
+
const nuxtApp = useNuxtApp();
|
|
36
|
+
return nuxtApp.$jtcsv;
|
|
37
|
+
}
|
|
38
|
+
function useJtcsvAsync() {
|
|
39
|
+
const nuxtApp = useNuxtApp();
|
|
40
|
+
const jtcsv = nuxtApp.$jtcsv;
|
|
41
|
+
return {
|
|
42
|
+
...jtcsv,
|
|
43
|
+
csvToJson: (jtcsv.csvToJsonAsync || jtcsv.csvToJson),
|
|
44
|
+
jsonToCsv: (jtcsv.jsonToCsvAsync || jtcsv.jsonToCsv),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function defineNuxtPlugin(fn) {
|
|
48
|
+
return fn;
|
|
49
|
+
}
|
|
50
|
+
function useNuxtApp() {
|
|
51
|
+
return { $jtcsv: {} };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../plugins/nuxt/index.ts"],"names":[],"mappings":";;AAiEA,4BAGC;AAKD,sCAUC;AA7DD,kBAAe,gBAAgB,CAAC,CAAC,OAAY,EAAE,UAA6B,EAAE,EAAE,EAAE;IAChF,MAAM,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAGlD,MAAM,KAAK,GAAG;QAEZ,SAAS,EAAE,CAAC,GAAW,EAAE,IAAuB,EAAE,EAAE;YAElD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;QACD,SAAS,EAAE,CAAC,IAAS,EAAE,IAAuB,EAAE,EAAE;YAChD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QAGD,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YACV,cAAc,EAAE,KAAK,EAAE,GAAW,EAAE,IAAuB,EAAE,EAAE;gBAC7D,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;gBACvC,OAAO,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC9B,CAAC;YACD,cAAc,EAAE,KAAK,EAAE,IAAS,EAAE,IAAuB,EAAE,EAAE;gBAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;gBACvC,OAAO,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC/B,CAAC;SACF,CAAC,CAAC,CAAC,EAAE,CAAC;QAGP,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACZ,gBAAgB,EAAE,CAAC,IAAa,EAAE,EAAE;gBAClC,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;gBAChE,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;SACF,CAAC,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IAGF,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAChC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAKH,SAAgB,QAAQ;IACtB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC;AAKD,SAAgB,aAAa;IAC3B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAa,CAAC;IAEpC,OAAO;QACL,GAAG,KAAK;QAER,SAAS,EAAE,CAAC,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,SAAS,CAAkD;QACrG,SAAS,EAAE,CAAC,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,SAAS,CAAmD;KACvG,CAAC;AACJ,CAAC;AAGD,SAAS,gBAAgB,CAAC,EAAO;IAC/B,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,UAAU;IAEjB,OAAO,EAAE,MAAM,EAAE,EAAS,EAAE,CAAC;AAC/B,CAAC","sourcesContent":["/**\r\n * Nuxt plugin for jtcsv\r\n * Provides jtcsv integration for Nuxt applications\r\n * @module plugins/nuxt\r\n */\r\n\r\nimport type { CsvToJsonOptions, JsonToCsvOptions } from '../../src/types';\r\n\r\n/**\r\n * Nuxt plugin options\r\n */\r\nexport interface NuxtPluginOptions {\r\n /** Whether to enable async functions (default: true) */\r\n async?: boolean;\r\n /** Whether to enable worker support (default: false) */\r\n workers?: boolean;\r\n}\r\n\r\n/**\r\n * Nuxt plugin implementation\r\n * This is a simplified version that works with Nuxt 3\r\n */\r\nexport default defineNuxtPlugin((nuxtApp: any, options: NuxtPluginOptions = {}) => {\r\n const { async = true, workers = false } = options;\r\n \r\n // Import jtcsv functions\r\n const jtcsv = {\r\n // Core functions\r\n csvToJson: (csv: string, opts?: CsvToJsonOptions) => {\r\n // This would be replaced with actual import in runtime\r\n return require('jtcsv').csvToJson(csv, opts);\r\n },\r\n jsonToCsv: (data: any, opts?: JsonToCsvOptions) => {\r\n return require('jtcsv').jsonToCsv(data, opts);\r\n },\r\n \r\n // Async versions if enabled\r\n ...(async ? {\r\n csvToJsonAsync: async (csv: string, opts?: CsvToJsonOptions) => {\r\n const { csvToJson } = require('jtcsv');\r\n return csvToJson(csv, opts);\r\n },\r\n jsonToCsvAsync: async (data: any, opts?: JsonToCsvOptions) => {\r\n const { jsonToCsv } = require('jtcsv');\r\n return jsonToCsv(data, opts);\r\n }\r\n } : {}),\r\n \r\n // Worker support if enabled\r\n ...(workers ? {\r\n createWorkerPool: (size?: number) => {\r\n const { WorkerPool } = require('../../src/workers/worker-pool');\r\n return new WorkerPool(size);\r\n }\r\n } : {})\r\n };\r\n\r\n // Provide jtcsv to Nuxt app\r\n nuxtApp.provide('jtcsv', jtcsv);\r\n nuxtApp.provide('useJtcsv', () => jtcsv);\r\n});\r\n\r\n/**\r\n * Nuxt composable for using jtcsv\r\n */\r\nexport function useJtcsv() {\r\n const nuxtApp = useNuxtApp();\r\n return nuxtApp.$jtcsv;\r\n}\r\n\r\n/**\r\n * Nuxt composable for async jtcsv operations\r\n */\r\nexport function useJtcsvAsync() {\r\n const nuxtApp = useNuxtApp();\r\n const jtcsv = nuxtApp.$jtcsv as any;\r\n \r\n return {\r\n ...jtcsv,\r\n // Ensure async methods are available\r\n csvToJson: (jtcsv.csvToJsonAsync || jtcsv.csvToJson) as (csv: string, opts?: CsvToJsonOptions) => any,\r\n jsonToCsv: (jtcsv.jsonToCsvAsync || jtcsv.jsonToCsv) as (data: any, opts?: JsonToCsvOptions) => string,\r\n };\r\n}\r\n\r\n// Helper functions for Nuxt module compatibility\r\nfunction defineNuxtPlugin(fn: any) {\r\n return fn;\r\n}\r\n\r\nfunction useNuxtApp() {\r\n // This would be provided by Nuxt runtime\r\n return { $jtcsv: {} as any };\r\n}"]}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseFormData = parseFormData;
|
|
4
|
+
exports.parseFormDataAsync = parseFormDataAsync;
|
|
5
|
+
exports.generateCsvResponse = generateCsvResponse;
|
|
6
|
+
exports.generateAsyncCsvResponse = generateAsyncCsvResponse;
|
|
7
|
+
exports.createCsvLoader = createCsvLoader;
|
|
8
|
+
exports.createCsvAction = createCsvAction;
|
|
9
|
+
exports.parseMultiPartFormData = parseMultiPartFormData;
|
|
10
|
+
exports.csvExport = csvExport;
|
|
11
|
+
const index_core_1 = require("../../index-core");
|
|
12
|
+
function normalizeFilename(filename) {
|
|
13
|
+
if (!filename || typeof filename !== 'string') {
|
|
14
|
+
return 'export.csv';
|
|
15
|
+
}
|
|
16
|
+
return filename.includes('.') ? filename : `${filename}.csv`;
|
|
17
|
+
}
|
|
18
|
+
async function extractCsvText(formData, fieldName) {
|
|
19
|
+
if (formData.has(fieldName)) {
|
|
20
|
+
const value = formData.get(fieldName);
|
|
21
|
+
if (value && typeof value.text === 'function') {
|
|
22
|
+
return await value.text();
|
|
23
|
+
}
|
|
24
|
+
if (value !== null) {
|
|
25
|
+
return String(value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
for (const value of formData.values()) {
|
|
29
|
+
if (value && typeof value.text === 'function') {
|
|
30
|
+
return await value.text();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
async function parseFormData(request, options = {}) {
|
|
36
|
+
if (!request || typeof request.formData !== 'function') {
|
|
37
|
+
throw new Error('parseFormData expects a Remix Request with formData()');
|
|
38
|
+
}
|
|
39
|
+
const { fieldName = 'file', ...csvOptions } = options;
|
|
40
|
+
const formData = await request.formData();
|
|
41
|
+
const csvText = await extractCsvText(formData, fieldName);
|
|
42
|
+
if (!csvText) {
|
|
43
|
+
throw new Error('No CSV file or field found in form data');
|
|
44
|
+
}
|
|
45
|
+
return await (0, index_core_1.csvToJson)(csvText, csvOptions);
|
|
46
|
+
}
|
|
47
|
+
async function parseFormDataAsync(request, options = {}) {
|
|
48
|
+
try {
|
|
49
|
+
return await parseFormData(request, options);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
throw new Error(`Failed to parse CSV from form data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function generateCsvResponse(data, filename = 'export.csv', options = {}) {
|
|
56
|
+
const safeName = normalizeFilename(filename);
|
|
57
|
+
const rows = Array.isArray(data) ? data : [data];
|
|
58
|
+
const csv = (0, index_core_1.jsonToCsv)(rows, options);
|
|
59
|
+
return new Response(csv, {
|
|
60
|
+
headers: {
|
|
61
|
+
'Content-Type': 'text/csv; charset=utf-8',
|
|
62
|
+
'Content-Disposition': `attachment; filename="${safeName}"`
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
async function generateAsyncCsvResponse(data, filename = 'export.csv', options = {}) {
|
|
67
|
+
const safeName = normalizeFilename(filename);
|
|
68
|
+
const rows = Array.isArray(data) ? data : [data];
|
|
69
|
+
const csv = await (0, index_core_1.jsonToCsv)(rows, options);
|
|
70
|
+
return new Response(csv, {
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'text/csv; charset=utf-8',
|
|
73
|
+
'Content-Disposition': `attachment; filename="${safeName}"`
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function createCsvLoader(dataLoader, filename = 'export.csv', options = {}) {
|
|
78
|
+
return async () => {
|
|
79
|
+
try {
|
|
80
|
+
const data = await (typeof dataLoader === 'function' ? dataLoader() : dataLoader);
|
|
81
|
+
return generateCsvResponse(data, filename, options);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return new Response(JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function createCsvAction(options = {}) {
|
|
89
|
+
return async ({ request }) => {
|
|
90
|
+
try {
|
|
91
|
+
const data = await parseFormData(request, options);
|
|
92
|
+
return new Response(JSON.stringify({ success: true, data }), { headers: { 'Content-Type': 'application/json' } });
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
return new Response(JSON.stringify({
|
|
96
|
+
success: false,
|
|
97
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
98
|
+
}), { status: 400, headers: { 'Content-Type': 'application/json' } });
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function parseMultiPartFormData(request, options = {}) {
|
|
103
|
+
const { multiple = false, ...csvOptions } = options;
|
|
104
|
+
const formData = await request.formData();
|
|
105
|
+
const results = [];
|
|
106
|
+
for (const [fieldName, value] of formData.entries()) {
|
|
107
|
+
if (value && typeof value.text === 'function') {
|
|
108
|
+
const csvText = await value.text();
|
|
109
|
+
if (csvText) {
|
|
110
|
+
const parsed = await (0, index_core_1.csvToJson)(csvText, csvOptions);
|
|
111
|
+
results.push(parsed);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (!multiple && results.length > 0) {
|
|
116
|
+
return results[0];
|
|
117
|
+
}
|
|
118
|
+
return results;
|
|
119
|
+
}
|
|
120
|
+
function csvExport(data, filename, options) {
|
|
121
|
+
return () => generateAsyncCsvResponse(data, filename, options);
|
|
122
|
+
}
|
|
123
|
+
exports.default = {
|
|
124
|
+
parseFormData,
|
|
125
|
+
parseFormDataAsync,
|
|
126
|
+
generateCsvResponse,
|
|
127
|
+
generateAsyncCsvResponse,
|
|
128
|
+
createCsvLoader,
|
|
129
|
+
createCsvAction,
|
|
130
|
+
parseMultiPartFormData,
|
|
131
|
+
csvExport,
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../plugins/remix/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Remix plugin for jtcsv\r\n * Provides utilities for CSV parsing and generation in Remix applications\r\n * @module plugins/remix\r\n */\r\n\r\nimport { csvToJson, jsonToCsv } from '../../index-core';\r\nimport type { CsvToJsonOptions, JsonToCsvOptions } from '../../src/types';\r\n\r\n/**\r\n * Remix Request type (simplified)\r\n */\r\ninterface RemixRequest {\r\n formData(): Promise<FormData>;\r\n}\r\n\r\n/**\r\n * Options for CSV parsing from form data\r\n */\r\nexport interface ParseFormDataOptions extends CsvToJsonOptions {\r\n /** Field name containing the CSV file (default: 'file') */\r\n fieldName?: string;\r\n}\r\n\r\n/**\r\n * Options for CSV response generation\r\n */\r\nexport interface GenerateCsvResponseOptions extends JsonToCsvOptions {\r\n // Additional options specific to CSV response\r\n}\r\n\r\n/**\r\n * Normalize filename for CSV download\r\n */\r\nfunction normalizeFilename(filename?: string): string {\r\n if (!filename || typeof filename !== 'string') {\r\n return 'export.csv';\r\n }\r\n return filename.includes('.') ? filename : `${filename}.csv`;\r\n}\r\n\r\n/**\r\n * Extract CSV text from FormData\r\n */\r\nasync function extractCsvText(formData: FormData, fieldName: string): Promise<string | null> {\r\n if (formData.has(fieldName)) {\r\n const value = formData.get(fieldName);\r\n if (value && typeof (value as any).text === 'function') {\r\n return await (value as any).text();\r\n }\r\n if (value !== null) {\r\n return String(value);\r\n }\r\n }\r\n\r\n for (const value of formData.values()) {\r\n if (value && typeof (value as any).text === 'function') {\r\n return await (value as any).text();\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse CSV from Remix form data\r\n * \r\n * @example\r\n * // In a Remix action:\r\n * export async function action({ request }: ActionArgs) {\r\n * const data = await parseFormData(request, { delimiter: ',' });\r\n * return json({ success: true, data });\r\n * }\r\n */\r\nexport async function parseFormData(\r\n request: RemixRequest,\r\n options: ParseFormDataOptions = {}\r\n): Promise<any[]> {\r\n if (!request || typeof request.formData !== 'function') {\r\n throw new Error('parseFormData expects a Remix Request with formData()');\r\n }\r\n\r\n const { fieldName = 'file', ...csvOptions } = options;\r\n const formData = await request.formData();\r\n const csvText = await extractCsvText(formData, fieldName);\r\n\r\n if (!csvText) {\r\n throw new Error('No CSV file or field found in form data');\r\n }\r\n\r\n return await csvToJson(csvText, csvOptions);\r\n}\r\n\r\n/**\r\n * Async version of parseFormData with better error handling\r\n */\r\nexport async function parseFormDataAsync(\r\n request: RemixRequest,\r\n options: ParseFormDataOptions = {}\r\n): Promise<any[]> {\r\n try {\r\n return await parseFormData(request, options);\r\n } catch (error) {\r\n throw new Error(`Failed to parse CSV from form data: ${error instanceof Error ? error.message : 'Unknown error'}`);\r\n }\r\n}\r\n\r\n/**\r\n * Generate a CSV response for Remix\r\n * \r\n * @example\r\n * // In a Remix loader:\r\n * export async function loader() {\r\n * const data = await getData();\r\n * return generateCsvResponse(data, 'export.csv');\r\n * }\r\n */\r\nexport function generateCsvResponse(\r\n data: any,\r\n filename: string = 'export.csv',\r\n options: GenerateCsvResponseOptions = {}\r\n): Response {\r\n const safeName = normalizeFilename(filename);\r\n const rows = Array.isArray(data) ? data : [data];\r\n const csv = jsonToCsv(rows, options);\r\n\r\n return new Response(csv, {\r\n headers: {\r\n 'Content-Type': 'text/csv; charset=utf-8',\r\n 'Content-Disposition': `attachment; filename=\"${safeName}\"`\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Async version of generateCsvResponse\r\n */\r\nexport async function generateAsyncCsvResponse(\r\n data: any,\r\n filename: string = 'export.csv',\r\n options: GenerateCsvResponseOptions = {}\r\n): Promise<Response> {\r\n const safeName = normalizeFilename(filename);\r\n const rows = Array.isArray(data) ? data : [data];\r\n const csv = await jsonToCsv(rows, options);\r\n\r\n return new Response(csv, {\r\n headers: {\r\n 'Content-Type': 'text/csv; charset=utf-8',\r\n 'Content-Disposition': `attachment; filename=\"${safeName}\"`\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * CSV loader helper for Remix\r\n * Creates a loader that returns CSV data\r\n * \r\n * @example\r\n * export const loader = createCsvLoader(async () => {\r\n * return await getData();\r\n * }, 'data.csv');\r\n */\r\nexport function createCsvLoader(\r\n dataLoader: () => Promise<any> | any,\r\n filename: string = 'export.csv',\r\n options: GenerateCsvResponseOptions = {}\r\n): () => Promise<Response> {\r\n return async () => {\r\n try {\r\n const data = await (typeof dataLoader === 'function' ? dataLoader() : dataLoader);\r\n return generateCsvResponse(data, filename, options);\r\n } catch (error) {\r\n return new Response(\r\n JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error' }),\r\n { status: 500, headers: { 'Content-Type': 'application/json' } }\r\n );\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * CSV action helper for Remix\r\n * Creates an action that parses CSV from form data\r\n * \r\n * @example\r\n * export const action = createCsvAction({ delimiter: ',' });\r\n */\r\nexport function createCsvAction(\r\n options: ParseFormDataOptions = {}\r\n): (args: { request: RemixRequest }) => Promise<Response> {\r\n return async ({ request }) => {\r\n try {\r\n const data = await parseFormData(request, options);\r\n return new Response(\r\n JSON.stringify({ success: true, data }),\r\n { headers: { 'Content-Type': 'application/json' } }\r\n );\r\n } catch (error) {\r\n return new Response(\r\n JSON.stringify({ \r\n success: false, \r\n error: error instanceof Error ? error.message : 'Unknown error' \r\n }),\r\n { status: 400, headers: { 'Content-Type': 'application/json' } }\r\n );\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Multi-part form data CSV parser\r\n * Handles multiple CSV files in a single form\r\n */\r\nexport async function parseMultiPartFormData(\r\n request: RemixRequest,\r\n options: ParseFormDataOptions & { multiple?: boolean } = {}\r\n): Promise<any[] | any[][]> {\r\n const { multiple = false, ...csvOptions } = options;\r\n const formData = await request.formData();\r\n const results: any[][] = [];\r\n\r\n for (const [fieldName, value] of formData.entries()) {\r\n if (value && typeof (value as any).text === 'function') {\r\n const csvText = await (value as any).text();\r\n if (csvText) {\r\n const parsed = await csvToJson(csvText, csvOptions);\r\n results.push(parsed);\r\n }\r\n }\r\n }\r\n\r\n if (!multiple && results.length > 0) {\r\n return results[0];\r\n }\r\n\r\n return results;\r\n}\r\n\r\n/**\r\n * CSV export utility for Remix routes\r\n */\r\nexport function csvExport(\r\n data: any,\r\n filename?: string,\r\n options?: GenerateCsvResponseOptions\r\n): () => Promise<Response> {\r\n return () => generateAsyncCsvResponse(data, filename, options);\r\n}\r\n\r\nexport default {\r\n parseFormData,\r\n parseFormDataAsync,\r\n generateCsvResponse,\r\n generateAsyncCsvResponse,\r\n createCsvLoader,\r\n createCsvAction,\r\n parseMultiPartFormData,\r\n csvExport,\r\n};"]}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseCsv = parseCsv;
|
|
4
|
+
exports.parseCsvAsync = parseCsvAsync;
|
|
5
|
+
exports.generateCsv = generateCsv;
|
|
6
|
+
exports.generateAsyncCsv = generateAsyncCsv;
|
|
7
|
+
exports.createCsvLoader = createCsvLoader;
|
|
8
|
+
exports.createCsvAction = createCsvAction;
|
|
9
|
+
exports.parseMultiPartCsv = parseMultiPartCsv;
|
|
10
|
+
exports.csvExport = csvExport;
|
|
11
|
+
exports.createCsvHook = createCsvHook;
|
|
12
|
+
const index_core_1 = require("../../index-core");
|
|
13
|
+
function normalizeFilename(filename) {
|
|
14
|
+
if (!filename || typeof filename !== 'string') {
|
|
15
|
+
return 'export.csv';
|
|
16
|
+
}
|
|
17
|
+
return filename.includes('.') ? filename : `${filename}.csv`;
|
|
18
|
+
}
|
|
19
|
+
async function extractCsvText(formData, fieldName) {
|
|
20
|
+
if (formData.has(fieldName)) {
|
|
21
|
+
const value = formData.get(fieldName);
|
|
22
|
+
if (value && typeof value.text === 'function') {
|
|
23
|
+
return await value.text();
|
|
24
|
+
}
|
|
25
|
+
if (value !== null) {
|
|
26
|
+
return String(value);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (const value of formData.values()) {
|
|
30
|
+
if (value && typeof value.text === 'function') {
|
|
31
|
+
return await value.text();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
async function parseCsv(request, options = {}) {
|
|
37
|
+
if (!request || typeof request.text !== 'function') {
|
|
38
|
+
throw new Error('parseCsv expects a Request instance');
|
|
39
|
+
}
|
|
40
|
+
const { fieldName = 'file', formData: forceFormData, ...csvOptions } = options;
|
|
41
|
+
const contentType = request.headers?.get?.('content-type') || '';
|
|
42
|
+
let csvText = null;
|
|
43
|
+
if (forceFormData || contentType.includes('multipart/form-data')) {
|
|
44
|
+
const formData = await request.formData();
|
|
45
|
+
csvText = await extractCsvText(formData, fieldName);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
csvText = await request.text();
|
|
49
|
+
}
|
|
50
|
+
if (!csvText) {
|
|
51
|
+
throw new Error('No CSV payload found in request');
|
|
52
|
+
}
|
|
53
|
+
return await (0, index_core_1.csvToJson)(csvText, csvOptions);
|
|
54
|
+
}
|
|
55
|
+
async function parseCsvAsync(request, options = {}) {
|
|
56
|
+
try {
|
|
57
|
+
return await parseCsv(request, options);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new Error(`Failed to parse CSV from request: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function generateCsv(data, filename = 'export.csv', options = {}) {
|
|
64
|
+
const safeName = normalizeFilename(filename);
|
|
65
|
+
const rows = Array.isArray(data) ? data : [data];
|
|
66
|
+
const csv = (0, index_core_1.jsonToCsv)(rows, options);
|
|
67
|
+
return new Response(csv, {
|
|
68
|
+
headers: {
|
|
69
|
+
'Content-Type': 'text/csv; charset=utf-8',
|
|
70
|
+
'Content-Disposition': `attachment; filename="${safeName}"`
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async function generateAsyncCsv(data, filename = 'export.csv', options = {}) {
|
|
75
|
+
const safeName = normalizeFilename(filename);
|
|
76
|
+
const rows = Array.isArray(data) ? data : [data];
|
|
77
|
+
const csv = await (0, index_core_1.jsonToCsv)(rows, options);
|
|
78
|
+
return new Response(csv, {
|
|
79
|
+
headers: {
|
|
80
|
+
'Content-Type': 'text/csv; charset=utf-8',
|
|
81
|
+
'Content-Disposition': `attachment; filename="${safeName}"`
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function createCsvLoader(dataLoader, filename = 'export.csv', options = {}) {
|
|
86
|
+
return async () => {
|
|
87
|
+
try {
|
|
88
|
+
const data = await (typeof dataLoader === 'function' ? dataLoader() : dataLoader);
|
|
89
|
+
return generateCsv(data, filename, options);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return new Response(JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function createCsvAction(options = {}) {
|
|
97
|
+
return async ({ request }) => {
|
|
98
|
+
try {
|
|
99
|
+
const data = await parseCsv(request, options);
|
|
100
|
+
return new Response(JSON.stringify({ success: true, data }), { headers: { 'Content-Type': 'application/json' } });
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
return new Response(JSON.stringify({
|
|
104
|
+
success: false,
|
|
105
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
106
|
+
}), { status: 400, headers: { 'Content-Type': 'application/json' } });
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
async function parseMultiPartCsv(request, options = {}) {
|
|
111
|
+
const { multiple = false, ...csvOptions } = options;
|
|
112
|
+
const formData = await request.formData();
|
|
113
|
+
const results = [];
|
|
114
|
+
for (const [fieldName, value] of formData.entries()) {
|
|
115
|
+
if (value && typeof value.text === 'function') {
|
|
116
|
+
const csvText = await value.text();
|
|
117
|
+
if (csvText) {
|
|
118
|
+
const parsed = await (0, index_core_1.csvToJson)(csvText, csvOptions);
|
|
119
|
+
results.push(parsed);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!multiple && results.length > 0) {
|
|
124
|
+
return results[0];
|
|
125
|
+
}
|
|
126
|
+
return results;
|
|
127
|
+
}
|
|
128
|
+
function csvExport(data, filename, options) {
|
|
129
|
+
return () => generateAsyncCsv(data, filename, options);
|
|
130
|
+
}
|
|
131
|
+
function createCsvHook(options = {}) {
|
|
132
|
+
return {
|
|
133
|
+
async handle({ event, resolve }) {
|
|
134
|
+
event.locals.csv = {
|
|
135
|
+
parse: (request, opts) => parseCsv(request, { ...options.parseOptions, ...opts }),
|
|
136
|
+
parseAsync: (request, opts) => parseCsvAsync(request, { ...options.parseOptions, ...opts }),
|
|
137
|
+
generate: (data, filename, opts) => generateCsv(data, filename, { ...options.generateOptions, ...opts }),
|
|
138
|
+
generateAsync: (data, filename, opts) => generateAsyncCsv(data, filename, { ...options.generateOptions, ...opts }),
|
|
139
|
+
};
|
|
140
|
+
return resolve(event);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
exports.default = {
|
|
145
|
+
parseCsv,
|
|
146
|
+
parseCsvAsync,
|
|
147
|
+
generateCsv,
|
|
148
|
+
generateAsyncCsv,
|
|
149
|
+
createCsvLoader,
|
|
150
|
+
createCsvAction,
|
|
151
|
+
parseMultiPartCsv,
|
|
152
|
+
csvExport,
|
|
153
|
+
createCsvHook,
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../plugins/sveltekit/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * SvelteKit plugin for jtcsv\r\n * Provides utilities for CSV parsing and generation in SvelteKit applications\r\n * @module plugins/sveltekit\r\n */\r\n\r\nimport { csvToJson, jsonToCsv } from '../../index-core';\r\nimport type { CsvToJsonOptions, JsonToCsvOptions } from '../../src/types';\r\n\r\n/**\r\n * SvelteKit Request type (simplified)\r\n */\r\ninterface SvelteKitRequest {\r\n text(): Promise<string>;\r\n formData(): Promise<FormData>;\r\n headers?: {\r\n get(name: string): string | null;\r\n };\r\n}\r\n\r\n/**\r\n * Options for CSV parsing from request\r\n */\r\nexport interface ParseCsvOptions extends CsvToJsonOptions {\r\n /** Field name containing the CSV file (default: 'file') */\r\n fieldName?: string;\r\n /** Force form data parsing (default: auto-detect) */\r\n formData?: boolean;\r\n}\r\n\r\n/**\r\n * Options for CSV response generation\r\n */\r\nexport interface GenerateCsvOptions extends JsonToCsvOptions {\r\n // Additional options specific to CSV response\r\n}\r\n\r\n/**\r\n * Normalize filename for CSV download\r\n */\r\nfunction normalizeFilename(filename?: string): string {\r\n if (!filename || typeof filename !== 'string') {\r\n return 'export.csv';\r\n }\r\n return filename.includes('.') ? filename : `${filename}.csv`;\r\n}\r\n\r\n/**\r\n * Extract CSV text from FormData\r\n */\r\nasync function extractCsvText(formData: FormData, fieldName: string): Promise<string | null> {\r\n if (formData.has(fieldName)) {\r\n const value = formData.get(fieldName);\r\n if (value && typeof (value as any).text === 'function') {\r\n return await (value as any).text();\r\n }\r\n if (value !== null) {\r\n return String(value);\r\n }\r\n }\r\n\r\n for (const value of formData.values()) {\r\n if (value && typeof (value as any).text === 'function') {\r\n return await (value as any).text();\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse CSV from SvelteKit request\r\n * \r\n * @example\r\n * // In a SvelteKit endpoint:\r\n * export async function POST({ request }) {\r\n * const data = await parseCsv(request, { delimiter: ',' });\r\n * return json({ success: true, data });\r\n * }\r\n */\r\nexport async function parseCsv(\r\n request: SvelteKitRequest,\r\n options: ParseCsvOptions = {}\r\n): Promise<any[]> {\r\n if (!request || typeof request.text !== 'function') {\r\n throw new Error('parseCsv expects a Request instance');\r\n }\r\n\r\n const { fieldName = 'file', formData: forceFormData, ...csvOptions } = options;\r\n const contentType = request.headers?.get?.('content-type') || '';\r\n let csvText: string | null = null;\r\n\r\n if (forceFormData || contentType.includes('multipart/form-data')) {\r\n const formData = await request.formData();\r\n csvText = await extractCsvText(formData, fieldName);\r\n } else {\r\n csvText = await request.text();\r\n }\r\n\r\n if (!csvText) {\r\n throw new Error('No CSV payload found in request');\r\n }\r\n\r\n return await csvToJson(csvText, csvOptions);\r\n}\r\n\r\n/**\r\n * Async version of parseCsv with better error handling\r\n */\r\nexport async function parseCsvAsync(\r\n request: SvelteKitRequest,\r\n options: ParseCsvOptions = {}\r\n): Promise<any[]> {\r\n try {\r\n return await parseCsv(request, options);\r\n } catch (error) {\r\n throw new Error(`Failed to parse CSV from request: ${error instanceof Error ? error.message : 'Unknown error'}`);\r\n }\r\n}\r\n\r\n/**\r\n * Generate a CSV response for SvelteKit\r\n * \r\n * @example\r\n * // In a SvelteKit endpoint:\r\n * export async function GET() {\r\n * const data = await getData();\r\n * return generateCsv(data, 'export.csv');\r\n * }\r\n */\r\nexport function generateCsv(\r\n data: any,\r\n filename: string = 'export.csv',\r\n options: GenerateCsvOptions = {}\r\n): Response {\r\n const safeName = normalizeFilename(filename);\r\n const rows = Array.isArray(data) ? data : [data];\r\n const csv = jsonToCsv(rows, options);\r\n\r\n return new Response(csv, {\r\n headers: {\r\n 'Content-Type': 'text/csv; charset=utf-8',\r\n 'Content-Disposition': `attachment; filename=\"${safeName}\"`\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Async version of generateCsv\r\n */\r\nexport async function generateAsyncCsv(\r\n data: any,\r\n filename: string = 'export.csv',\r\n options: GenerateCsvOptions = {}\r\n): Promise<Response> {\r\n const safeName = normalizeFilename(filename);\r\n const rows = Array.isArray(data) ? data : [data];\r\n const csv = await jsonToCsv(rows, options);\r\n\r\n return new Response(csv, {\r\n headers: {\r\n 'Content-Type': 'text/csv; charset=utf-8',\r\n 'Content-Disposition': `attachment; filename=\"${safeName}\"`\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * CSV loader helper for SvelteKit\r\n * Creates a loader that returns CSV data\r\n * \r\n * @example\r\n * export const loader = createCsvLoader(async () => {\r\n * return await getData();\r\n * }, 'data.csv');\r\n */\r\nexport function createCsvLoader(\r\n dataLoader: () => Promise<any> | any,\r\n filename: string = 'export.csv',\r\n options: GenerateCsvOptions = {}\r\n): () => Promise<Response> {\r\n return async () => {\r\n try {\r\n const data = await (typeof dataLoader === 'function' ? dataLoader() : dataLoader);\r\n return generateCsv(data, filename, options);\r\n } catch (error) {\r\n return new Response(\r\n JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error' }),\r\n { status: 500, headers: { 'Content-Type': 'application/json' } }\r\n );\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * CSV action helper for SvelteKit\r\n * Creates an action that parses CSV from form data\r\n * \r\n * @example\r\n * export const action = createCsvAction({ delimiter: ',' });\r\n */\r\nexport function createCsvAction(\r\n options: ParseCsvOptions = {}\r\n): (args: { request: SvelteKitRequest }) => Promise<Response> {\r\n return async ({ request }) => {\r\n try {\r\n const data = await parseCsv(request, options);\r\n return new Response(\r\n JSON.stringify({ success: true, data }),\r\n { headers: { 'Content-Type': 'application/json' } }\r\n );\r\n } catch (error) {\r\n return new Response(\r\n JSON.stringify({ \r\n success: false, \r\n error: error instanceof Error ? error.message : 'Unknown error' \r\n }),\r\n { status: 400, headers: { 'Content-Type': 'application/json' } }\r\n );\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Multi-part form data CSV parser\r\n * Handles multiple CSV files in a single request\r\n */\r\nexport async function parseMultiPartCsv(\r\n request: SvelteKitRequest,\r\n options: ParseCsvOptions & { multiple?: boolean } = {}\r\n): Promise<any[] | any[][]> {\r\n const { multiple = false, ...csvOptions } = options;\r\n const formData = await request.formData();\r\n const results: any[][] = [];\r\n\r\n for (const [fieldName, value] of formData.entries()) {\r\n if (value && typeof (value as any).text === 'function') {\r\n const csvText = await (value as any).text();\r\n if (csvText) {\r\n const parsed = await csvToJson(csvText, csvOptions);\r\n results.push(parsed);\r\n }\r\n }\r\n }\r\n\r\n if (!multiple && results.length > 0) {\r\n return results[0];\r\n }\r\n\r\n return results;\r\n}\r\n\r\n/**\r\n * CSV export utility for SvelteKit routes\r\n */\r\nexport function csvExport(\r\n data: any,\r\n filename?: string,\r\n options?: GenerateCsvOptions\r\n): () => Promise<Response> {\r\n return () => generateAsyncCsv(data, filename, options);\r\n}\r\n\r\n/**\r\n * SvelteKit server hook for CSV processing\r\n * Can be used in hooks.server.js/ts\r\n */\r\nexport function createCsvHook(options: {\r\n parseOptions?: ParseCsvOptions;\r\n generateOptions?: GenerateCsvOptions;\r\n} = {}) {\r\n return {\r\n async handle({ event, resolve }: { event: any; resolve: any }) {\r\n // Add CSV utilities to event.locals\r\n event.locals.csv = {\r\n parse: (request: SvelteKitRequest, opts?: ParseCsvOptions) => \r\n parseCsv(request, { ...options.parseOptions, ...opts }),\r\n parseAsync: (request: SvelteKitRequest, opts?: ParseCsvOptions) => \r\n parseCsvAsync(request, { ...options.parseOptions, ...opts }),\r\n generate: (data: any, filename?: string, opts?: GenerateCsvOptions) => \r\n generateCsv(data, filename, { ...options.generateOptions, ...opts }),\r\n generateAsync: (data: any, filename?: string, opts?: GenerateCsvOptions) => \r\n generateAsyncCsv(data, filename, { ...options.generateOptions, ...opts }),\r\n };\r\n\r\n return resolve(event);\r\n }\r\n };\r\n}\r\n\r\nexport default {\r\n parseCsv,\r\n parseCsvAsync,\r\n generateCsv,\r\n generateAsyncCsv,\r\n createCsvLoader,\r\n createCsvAction,\r\n parseMultiPartCsv,\r\n csvExport,\r\n createCsvHook,\r\n};"]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCsvProcedure = createCsvProcedure;
|
|
4
|
+
exports.createAsyncCsvProcedure = createAsyncCsvProcedure;
|
|
5
|
+
exports.createCsvResponseProcedure = createCsvResponseProcedure;
|
|
6
|
+
exports.createAsyncCsvResponseProcedure = createAsyncCsvResponseProcedure;
|
|
7
|
+
exports.createCsvRouter = createCsvRouter;
|
|
8
|
+
exports.createCsvMiddleware = createCsvMiddleware;
|
|
9
|
+
const index_core_1 = require("../../index-core");
|
|
10
|
+
function extractCsvText(input) {
|
|
11
|
+
if (typeof input === 'string') {
|
|
12
|
+
return input;
|
|
13
|
+
}
|
|
14
|
+
if (input && typeof input === 'object' && typeof input.csv === 'string') {
|
|
15
|
+
return input.csv;
|
|
16
|
+
}
|
|
17
|
+
if (input && typeof input === 'object' && input.file && typeof input.file.text === 'function') {
|
|
18
|
+
return input.file.text();
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
function createCsvProcedure(t, schema, options = {}) {
|
|
23
|
+
if (!t || !t.procedure) {
|
|
24
|
+
throw new Error('createCsvProcedure expects initTRPC instance');
|
|
25
|
+
}
|
|
26
|
+
return t.procedure
|
|
27
|
+
.input(schema)
|
|
28
|
+
.use(async ({ input, next }) => {
|
|
29
|
+
const csvText = extractCsvText(input);
|
|
30
|
+
if (!csvText) {
|
|
31
|
+
throw new Error('CSV input must be a string or { csv: string }');
|
|
32
|
+
}
|
|
33
|
+
if (options.async) {
|
|
34
|
+
const parsed = await (0, index_core_1.csvToJson)(csvText, options);
|
|
35
|
+
return next({ input: parsed });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const parsed = (0, index_core_1.csvToJson)(csvText, options);
|
|
39
|
+
return next({ input: parsed });
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function createAsyncCsvProcedure(t, schema, options = {}) {
|
|
44
|
+
return createCsvProcedure(t, schema, { ...options, async: true });
|
|
45
|
+
}
|
|
46
|
+
function createCsvResponseProcedure(t, schema, options = {}) {
|
|
47
|
+
if (!t || !t.procedure) {
|
|
48
|
+
throw new Error('createCsvResponseProcedure expects initTRPC instance');
|
|
49
|
+
}
|
|
50
|
+
return t.procedure
|
|
51
|
+
.input(schema)
|
|
52
|
+
.use(async ({ input, next }) => {
|
|
53
|
+
const { filename = 'export.csv', asResponse = false, ...csvOptions } = options;
|
|
54
|
+
const rows = Array.isArray(input) ? input : [input];
|
|
55
|
+
if (options.async) {
|
|
56
|
+
const csv = await (0, index_core_1.jsonToCsv)(rows, csvOptions);
|
|
57
|
+
if (asResponse) {
|
|
58
|
+
const response = new Response(csv, {
|
|
59
|
+
headers: {
|
|
60
|
+
'Content-Type': 'text/csv; charset=utf-8',
|
|
61
|
+
'Content-Disposition': `attachment; filename="${filename}"`
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return next({ input: response });
|
|
65
|
+
}
|
|
66
|
+
return next({ input: csv });
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const csv = (0, index_core_1.jsonToCsv)(rows, csvOptions);
|
|
70
|
+
if (asResponse) {
|
|
71
|
+
const response = new Response(csv, {
|
|
72
|
+
headers: {
|
|
73
|
+
'Content-Type': 'text/csv; charset=utf-8',
|
|
74
|
+
'Content-Disposition': `attachment; filename="${filename}"`
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return next({ input: response });
|
|
78
|
+
}
|
|
79
|
+
return next({ input: csv });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function createAsyncCsvResponseProcedure(t, schema, options = {}) {
|
|
84
|
+
return createCsvResponseProcedure(t, schema, { ...options, async: true });
|
|
85
|
+
}
|
|
86
|
+
function createCsvRouter(t, options = {}) {
|
|
87
|
+
if (!t || !t.procedure) {
|
|
88
|
+
throw new Error('createCsvRouter expects initTRPC instance');
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
parse: createCsvProcedure(t, z.string(), options.parseOptions),
|
|
92
|
+
parseAsync: createAsyncCsvProcedure(t, z.string(), options.parseOptions),
|
|
93
|
+
export: createCsvResponseProcedure(t, z.array(z.any()), options.responseOptions),
|
|
94
|
+
exportAsync: createAsyncCsvResponseProcedure(t, z.array(z.any()), options.responseOptions),
|
|
95
|
+
batch: t.procedure
|
|
96
|
+
.input(z.array(z.string()))
|
|
97
|
+
.use(async ({ input, next }) => {
|
|
98
|
+
const results = await Promise.all(input.map((csv) => (0, index_core_1.csvToJson)(csv, options.parseOptions)));
|
|
99
|
+
return next({ input: results });
|
|
100
|
+
}),
|
|
101
|
+
batchAsync: t.procedure
|
|
102
|
+
.input(z.array(z.string()))
|
|
103
|
+
.use(async ({ input, next }) => {
|
|
104
|
+
const results = await Promise.all(input.map((csv) => (0, index_core_1.csvToJson)(csv, options.parseOptions)));
|
|
105
|
+
return next({ input: results });
|
|
106
|
+
}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function createCsvMiddleware(options = {}) {
|
|
110
|
+
return async ({ ctx, next }) => {
|
|
111
|
+
const enhancedCtx = {
|
|
112
|
+
...ctx,
|
|
113
|
+
csv: {
|
|
114
|
+
parse: (csvText) => (0, index_core_1.csvToJson)(csvText, options),
|
|
115
|
+
parseAsync: async (csvText) => await (0, index_core_1.csvToJson)(csvText, options),
|
|
116
|
+
generate: (data, opts) => (0, index_core_1.jsonToCsv)(data, { ...options, ...opts }),
|
|
117
|
+
generateAsync: async (data, opts) => await (0, index_core_1.jsonToCsv)(data, { ...options, ...opts }),
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
return next({ ctx: enhancedCtx });
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const z = {
|
|
124
|
+
string: () => ({ _type: 'string' }),
|
|
125
|
+
array: (schema) => ({ _type: 'array', schema }),
|
|
126
|
+
any: () => ({ _type: 'any' }),
|
|
127
|
+
};
|
|
128
|
+
exports.default = {
|
|
129
|
+
createCsvProcedure,
|
|
130
|
+
createAsyncCsvProcedure,
|
|
131
|
+
createCsvResponseProcedure,
|
|
132
|
+
createAsyncCsvResponseProcedure,
|
|
133
|
+
createCsvRouter,
|
|
134
|
+
createCsvMiddleware,
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../plugins/trpc/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * tRPC plugin for jtcsv\r\n * Provides utilities for CSV parsing and generation in tRPC applications\r\n * @module plugins/trpc\r\n */\r\n\r\nimport { csvToJson, jsonToCsv } from '../../index-core';\r\nimport type { CsvToJsonOptions, JsonToCsvOptions } from '../../src/types';\r\n\r\n/**\r\n * tRPC context type (simplified)\r\n */\r\ninterface TRPCContext {\r\n // tRPC context properties\r\n}\r\n\r\n/**\r\n * tRPC procedure type (simplified)\r\n */\r\ninterface TRPCProcedure {\r\n input(schema: any): any;\r\n use(middleware: any): any;\r\n}\r\n\r\n/**\r\n * tRPC instance type (simplified)\r\n */\r\ninterface TRPCInstance {\r\n procedure: TRPCProcedure;\r\n}\r\n\r\n/**\r\n * Options for CSV parsing in tRPC procedures\r\n */\r\nexport interface CsvProcedureOptions extends CsvToJsonOptions {\r\n /** Whether to return raw CSV text instead of parsed JSON */\r\n raw?: boolean;\r\n /** Whether to use async parsing */\r\n async?: boolean;\r\n}\r\n\r\n/**\r\n * Options for CSV generation in tRPC procedures\r\n */\r\nexport interface CsvResponseOptions extends JsonToCsvOptions {\r\n /** Filename for download (default: 'export.csv') */\r\n filename?: string;\r\n /** Whether to return as Response object */\r\n asResponse?: boolean;\r\n /** Whether to use async generation */\r\n async?: boolean;\r\n}\r\n\r\n/**\r\n * Extract CSV text from various input formats\r\n */\r\nfunction extractCsvText(input: any): string | null {\r\n if (typeof input === 'string') {\r\n return input;\r\n }\r\n if (input && typeof input === 'object' && typeof input.csv === 'string') {\r\n return input.csv;\r\n }\r\n if (input && typeof input === 'object' && input.file && typeof input.file.text === 'function') {\r\n return input.file.text();\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Create a tRPC procedure for CSV parsing\r\n * \r\n * @example\r\n * // In your tRPC router:\r\n * import { createCsvProcedure } from 'jtcsv/plugins/trpc';\r\n * \r\n * export const csvRouter = t.router({\r\n * parse: createCsvProcedure(t, z.string(), { delimiter: ',' })\r\n * });\r\n */\r\nexport function createCsvProcedure(\r\n t: TRPCInstance,\r\n schema: any,\r\n options: CsvProcedureOptions = {}\r\n): any {\r\n if (!t || !t.procedure) {\r\n throw new Error('createCsvProcedure expects initTRPC instance');\r\n }\r\n\r\n return t.procedure\r\n .input(schema)\r\n .use(async ({ input, next }: { input: any; next: any }) => {\r\n const csvText = extractCsvText(input);\r\n if (!csvText) {\r\n throw new Error('CSV input must be a string or { csv: string }');\r\n }\r\n\r\n if (options.async) {\r\n const parsed = await csvToJson(csvText, options);\r\n return next({ input: parsed });\r\n } else {\r\n const parsed = csvToJson(csvText, options);\r\n return next({ input: parsed });\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Async version of createCsvProcedure\r\n */\r\nexport function createAsyncCsvProcedure(\r\n t: TRPCInstance,\r\n schema: any,\r\n options: CsvProcedureOptions = {}\r\n): any {\r\n return createCsvProcedure(t, schema, { ...options, async: true });\r\n}\r\n\r\n/**\r\n * Create a tRPC procedure for CSV generation\r\n * \r\n * @example\r\n * // In your tRPC router:\r\n * import { createCsvResponseProcedure } from 'jtcsv/plugins/trpc';\r\n * \r\n * export const csvRouter = t.router({\r\n * export: createCsvResponseProcedure(t, z.array(z.any()), { filename: 'data.csv' })\r\n * });\r\n */\r\nexport function createCsvResponseProcedure(\r\n t: TRPCInstance,\r\n schema: any,\r\n options: CsvResponseOptions = {}\r\n): any {\r\n if (!t || !t.procedure) {\r\n throw new Error('createCsvResponseProcedure expects initTRPC instance');\r\n }\r\n\r\n return t.procedure\r\n .input(schema)\r\n .use(async ({ input, next }: { input: any; next: any }) => {\r\n const { filename = 'export.csv', asResponse = false, ...csvOptions } = options;\r\n const rows = Array.isArray(input) ? input : [input];\r\n \r\n if (options.async) {\r\n const csv = await jsonToCsv(rows, csvOptions);\r\n \r\n if (asResponse) {\r\n const response = new Response(csv, {\r\n headers: {\r\n 'Content-Type': 'text/csv; charset=utf-8',\r\n 'Content-Disposition': `attachment; filename=\"${filename}\"`\r\n }\r\n });\r\n return next({ input: response });\r\n }\r\n \r\n return next({ input: csv });\r\n } else {\r\n const csv = jsonToCsv(rows, csvOptions);\r\n \r\n if (asResponse) {\r\n const response = new Response(csv, {\r\n headers: {\r\n 'Content-Type': 'text/csv; charset=utf-8',\r\n 'Content-Disposition': `attachment; filename=\"${filename}\"`\r\n }\r\n });\r\n return next({ input: response });\r\n }\r\n \r\n return next({ input: csv });\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Async version of createCsvResponseProcedure\r\n */\r\nexport function createAsyncCsvResponseProcedure(\r\n t: TRPCInstance,\r\n schema: any,\r\n options: CsvResponseOptions = {}\r\n): any {\r\n return createCsvResponseProcedure(t, schema, { ...options, async: true });\r\n}\r\n\r\n/**\r\n * Create a complete tRPC router for CSV operations\r\n * \r\n * @example\r\n * // In your tRPC setup:\r\n * import { createCsvRouter } from 'jtcsv/plugins/trpc';\r\n * \r\n * export const csvRouter = createCsvRouter(t);\r\n */\r\nexport function createCsvRouter(t: TRPCInstance, options: {\r\n parseOptions?: CsvProcedureOptions;\r\n responseOptions?: CsvResponseOptions;\r\n} = {}) {\r\n if (!t || !t.procedure) {\r\n throw new Error('createCsvRouter expects initTRPC instance');\r\n }\r\n\r\n return {\r\n parse: createCsvProcedure(t, z.string(), options.parseOptions),\r\n parseAsync: createAsyncCsvProcedure(t, z.string(), options.parseOptions),\r\n export: createCsvResponseProcedure(t, z.array(z.any()), options.responseOptions),\r\n exportAsync: createAsyncCsvResponseProcedure(t, z.array(z.any()), options.responseOptions),\r\n batch: t.procedure\r\n .input(z.array(z.string()))\r\n .use(async ({ input, next }: { input: string[]; next: any }) => {\r\n const results = await Promise.all(\r\n input.map((csv: string) => csvToJson(csv, options.parseOptions))\r\n );\r\n return next({ input: results });\r\n }),\r\n batchAsync: t.procedure\r\n .input(z.array(z.string()))\r\n .use(async ({ input, next }: { input: string[]; next: any }) => {\r\n const results = await Promise.all(\r\n input.map((csv: string) => csvToJson(csv, options.parseOptions))\r\n );\r\n return next({ input: results });\r\n }),\r\n };\r\n}\r\n\r\n/**\r\n * tRPC middleware for CSV processing\r\n * Adds CSV utilities to tRPC context\r\n */\r\nexport function createCsvMiddleware(options: CsvProcedureOptions = {}) {\r\n return async ({ ctx, next }: { ctx: TRPCContext; next: any }) => {\r\n const enhancedCtx = {\r\n ...ctx,\r\n csv: {\r\n parse: (csvText: string) => csvToJson(csvText, options),\r\n parseAsync: async (csvText: string) => await csvToJson(csvText, options),\r\n generate: (data: any, opts?: JsonToCsvOptions) => jsonToCsv(data, { ...options, ...opts }),\r\n generateAsync: async (data: any, opts?: JsonToCsvOptions) => \r\n await jsonToCsv(data, { ...options, ...opts }),\r\n }\r\n };\r\n\r\n return next({ ctx: enhancedCtx });\r\n };\r\n}\r\n\r\n/**\r\n * Zod schema for CSV input validation\r\n * Note: This is a placeholder - in real usage, import zod\r\n */\r\nconst z = {\r\n string: () => ({ _type: 'string' }),\r\n array: (schema: any) => ({ _type: 'array', schema }),\r\n any: () => ({ _type: 'any' }),\r\n};\r\n\r\nexport default {\r\n createCsvProcedure,\r\n createAsyncCsvProcedure,\r\n createCsvResponseProcedure,\r\n createAsyncCsvResponseProcedure,\r\n createCsvRouter,\r\n createCsvMiddleware,\r\n};"]}
|
package/dist/run-demo.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
console.log('š Starting jtcsv demos...\n');
|
|
11
|
+
async function runDemo() {
|
|
12
|
+
console.log('š Available demos:');
|
|
13
|
+
console.log('1. Express API Demo');
|
|
14
|
+
console.log('2. Plugin Examples');
|
|
15
|
+
console.log('3. Web Demo (Vue.js)');
|
|
16
|
+
console.log('4. CLI TUI Interface');
|
|
17
|
+
console.log('5. All demos\n');
|
|
18
|
+
console.log('š Starting Express API Demo...');
|
|
19
|
+
const expressDemo = path_1.default.join(__dirname, 'examples', 'express-api.js');
|
|
20
|
+
if (fs_1.default.existsSync(expressDemo)) {
|
|
21
|
+
const child = (0, child_process_1.spawn)('node', [expressDemo], {
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
shell: true
|
|
24
|
+
});
|
|
25
|
+
child.on('error', (error) => {
|
|
26
|
+
console.error(`ā Failed to start demo: ${error.message}`);
|
|
27
|
+
});
|
|
28
|
+
process.on('SIGINT', () => {
|
|
29
|
+
console.log('\nš Stopping demo...');
|
|
30
|
+
child.kill('SIGINT');
|
|
31
|
+
process.exit(0);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.log('ā Express demo not found. Run examples directly:');
|
|
36
|
+
console.log(' node examples/express-api.js');
|
|
37
|
+
console.log(' node examples/plugin-excel-exporter.js');
|
|
38
|
+
console.log(' cd demo && npm run dev');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
process.on('uncaughtException', (error) => {
|
|
42
|
+
console.error(`\nā Demo error: ${error.message}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
});
|
|
45
|
+
runDemo().catch(error => {
|
|
46
|
+
console.error(`\nā Failed to run demo: ${error.message}`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=run-demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-demo.js","sourceRoot":"","sources":["../run-demo.ts"],"names":[],"mappings":";;;;;;AASA,iDAAsC;AACtC,gDAAwB;AACxB,4CAAoB;AAEpB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAE5C,KAAK,UAAU,OAAO;IACpB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAG9B,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;IAEvE,IAAI,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAA,qBAAK,EAAC,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE;YACzC,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,OAAO,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACxB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAGD,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;IACxC,OAAO,CAAC,KAAK,CAAC,mBAAmB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAGH,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACtB,OAAO,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\n\n/**\n * Run Demo Script for jtcsv\n * \n * Starts various demo servers and examples\n * Usage: npm run demo\n */\n\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport fs from \"fs\";\n\nconsole.log('š Starting jtcsv demos...\\n');\n\nasync function runDemo() {\n console.log('š Available demos:');\n console.log('1. Express API Demo');\n console.log('2. Plugin Examples');\n console.log('3. Web Demo (Vue.js)');\n console.log('4. CLI TUI Interface');\n console.log('5. All demos\\n');\n\n // For now, just start the Express API demo\n console.log('š Starting Express API Demo...');\n \n const expressDemo = path.join(__dirname, 'examples', 'express-api.js');\n \n if (fs.existsSync(expressDemo)) {\n const child = spawn('node', [expressDemo], {\n stdio: 'inherit',\n shell: true\n });\n \n child.on('error', (error) => {\n console.error(`ā Failed to start demo: ${error.message}`);\n });\n \n process.on('SIGINT', () => {\n console.log('\\nš Stopping demo...');\n child.kill('SIGINT');\n process.exit(0);\n });\n } else {\n console.log('ā Express demo not found. Run examples directly:');\n console.log(' node examples/express-api.js');\n console.log(' node examples/plugin-excel-exporter.js');\n console.log(' cd demo && npm run dev');\n }\n}\n\n// Handle errors\nprocess.on('uncaughtException', (error) => {\n console.error(`\\nā Demo error: ${error.message}`);\n process.exit(1);\n});\n\n// Run demo\nrunDemo().catch(error => {\n console.error(`\\nā Failed to run demo: ${error.message}`);\n process.exit(1);\n});\r\n"]}
|