jtcsv 2.1.1 → 2.1.3

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.
@@ -0,0 +1,21 @@
1
+ const { defineNuxtModule, addPlugin, addImports, createResolver } = require('@nuxt/kit');
2
+
3
+ module.exports = defineNuxtModule({
4
+ meta: {
5
+ name: '@jtcsv/nuxt',
6
+ configKey: 'jtcsv'
7
+ },
8
+ defaults: {
9
+ autoimport: true
10
+ },
11
+ setup(options) {
12
+ const resolver = createResolver(__dirname);
13
+ addPlugin(resolver.resolve('runtime/plugin'));
14
+
15
+ if (options.autoimport !== false) {
16
+ addImports([
17
+ { name: 'useJtcsv', from: resolver.resolve('runtime/composables/useJtcsv') }
18
+ ]);
19
+ }
20
+ }
21
+ });
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@jtcsv/nuxt",
3
+ "version": "1.0.0",
4
+ "description": "Nuxt module for JTCSV (auto-imported composable)",
5
+ "main": "index.js",
6
+ "keywords": [
7
+ "nuxt",
8
+ "module",
9
+ "csv",
10
+ "json",
11
+ "converter",
12
+ "jtcsv"
13
+ ],
14
+ "author": "Ruslan Fomenko",
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/Linol-Hamelton/jtcsv.git",
19
+ "directory": "plugins/nuxt"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
23
+ },
24
+ "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/nuxt#readme",
25
+ "peerDependencies": {
26
+ "@nuxt/kit": "^3.0.0",
27
+ "jtcsv": "^2.1.3",
28
+ "nuxt": "^3.0.0"
29
+ },
30
+ "files": [
31
+ "index.js",
32
+ "README.md",
33
+ "runtime/"
34
+ ]
35
+ }
@@ -0,0 +1,6 @@
1
+ import { useNuxtApp } from '#app';
2
+
3
+ export const useJtcsv = () => {
4
+ const { $jtcsv } = useNuxtApp();
5
+ return $jtcsv;
6
+ };
@@ -0,0 +1,6 @@
1
+ import { defineNuxtPlugin } from '#app';
2
+ import * as jtcsv from 'jtcsv';
3
+
4
+ export default defineNuxtPlugin((nuxtApp) => {
5
+ nuxtApp.provide('jtcsv', jtcsv);
6
+ });
@@ -0,0 +1,26 @@
1
+ # @jtcsv/remix
2
+
3
+ Remix helpers for JTCSV.
4
+
5
+ ## Install
6
+ ```bash
7
+ npm install @jtcsv/remix jtcsv
8
+ ```
9
+
10
+ ## Usage
11
+ ```typescript
12
+ import { parseFormData, generateCsvResponse } from 'jtcsv/remix';
13
+
14
+ export async function action({ request }) {
15
+ const rows = await parseFormData(request, { delimiter: ',' });
16
+ return { parsed: rows };
17
+ }
18
+
19
+ export async function loader() {
20
+ return generateCsvResponse([{ id: 1, name: 'John' }], 'export.csv');
21
+ }
22
+ ```
23
+
24
+ ## Notes
25
+ - `parseFormData` looks for a file field named `file` by default.
26
+ - You can override the field name with `{ fieldName: 'upload' }`.
@@ -0,0 +1,16 @@
1
+ import type { CsvToJsonOptions, JsonToCsvOptions } from 'jtcsv';
2
+
3
+ export interface RemixCsvParseOptions extends CsvToJsonOptions {
4
+ fieldName?: string;
5
+ }
6
+
7
+ export function parseFormData(
8
+ request: Request,
9
+ options?: RemixCsvParseOptions
10
+ ): Promise<unknown[]>;
11
+
12
+ export function generateCsvResponse(
13
+ data: unknown[] | Record<string, unknown>,
14
+ filename?: string,
15
+ options?: JsonToCsvOptions
16
+ ): Response;
@@ -0,0 +1,62 @@
1
+ const jtcsv = require('jtcsv');
2
+
3
+ function normalizeFilename(filename) {
4
+ if (!filename || typeof filename !== 'string') {
5
+ return 'export.csv';
6
+ }
7
+ return filename.includes('.') ? filename : `${filename}.csv`;
8
+ }
9
+
10
+ async function extractCsvText(formData, fieldName) {
11
+ if (formData.has(fieldName)) {
12
+ const value = formData.get(fieldName);
13
+ if (value && typeof value.text === 'function') {
14
+ return await value.text();
15
+ }
16
+ if (value != null) {
17
+ return String(value);
18
+ }
19
+ }
20
+
21
+ for (const value of formData.values()) {
22
+ if (value && typeof value.text === 'function') {
23
+ return await value.text();
24
+ }
25
+ }
26
+
27
+ return null;
28
+ }
29
+
30
+ async function parseFormData(request, options = {}) {
31
+ if (!request || typeof request.formData !== 'function') {
32
+ throw new Error('parseFormData expects a Remix Request with formData()');
33
+ }
34
+
35
+ const { fieldName = 'file', ...csvOptions } = options;
36
+ const formData = await request.formData();
37
+ const csvText = await extractCsvText(formData, fieldName);
38
+
39
+ if (!csvText) {
40
+ throw new Error('No CSV file or field found in form data');
41
+ }
42
+
43
+ return jtcsv.csvToJson(csvText, csvOptions);
44
+ }
45
+
46
+ function generateCsvResponse(data, filename = 'export.csv', options = {}) {
47
+ const safeName = normalizeFilename(filename);
48
+ const rows = Array.isArray(data) ? data : [data];
49
+ const csv = jtcsv.jsonToCsv(rows, options);
50
+
51
+ return new Response(csv, {
52
+ headers: {
53
+ 'Content-Type': 'text/csv; charset=utf-8',
54
+ 'Content-Disposition': `attachment; filename="${safeName}"`
55
+ }
56
+ });
57
+ }
58
+
59
+ module.exports = {
60
+ parseFormData,
61
+ generateCsvResponse
62
+ };
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@jtcsv/remix",
3
+ "version": "1.0.0",
4
+ "description": "Remix helpers for JTCSV (form-data parsing and CSV responses)",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "keywords": [
8
+ "remix",
9
+ "csv",
10
+ "json",
11
+ "converter",
12
+ "jtcsv",
13
+ "formdata",
14
+ "response"
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/remix"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
25
+ },
26
+ "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/remix#readme",
27
+ "peerDependencies": {
28
+ "jtcsv": "^2.1.3"
29
+ },
30
+ "files": [
31
+ "index.js",
32
+ "index.d.ts",
33
+ "README.md"
34
+ ]
35
+ }
@@ -0,0 +1,28 @@
1
+ # @jtcsv/sveltekit
2
+
3
+ SvelteKit helpers for JTCSV.
4
+
5
+ ## Install
6
+ ```bash
7
+ npm install @jtcsv/sveltekit jtcsv
8
+ ```
9
+
10
+ ## Usage
11
+ ```typescript
12
+ import { parseCsv, generateCsv } from 'jtcsv/sveltekit';
13
+
14
+ export const actions = {
15
+ upload: async ({ request }) => {
16
+ const rows = await parseCsv(request, { delimiter: ',' });
17
+ return { success: true, rows };
18
+ }
19
+ };
20
+
21
+ export async function GET() {
22
+ return generateCsv([{ id: 1, name: 'John' }], 'export.csv');
23
+ }
24
+ ```
25
+
26
+ ## Notes
27
+ - `parseCsv` reads `request.text()` by default.
28
+ - Use `{ formData: true, fieldName: 'file' }` for multipart uploads.
@@ -0,0 +1,17 @@
1
+ import type { CsvToJsonOptions, JsonToCsvOptions } from 'jtcsv';
2
+
3
+ export interface SvelteKitCsvParseOptions extends CsvToJsonOptions {
4
+ fieldName?: string;
5
+ formData?: boolean;
6
+ }
7
+
8
+ export function parseCsv(
9
+ request: Request,
10
+ options?: SvelteKitCsvParseOptions
11
+ ): Promise<unknown[]>;
12
+
13
+ export function generateCsv(
14
+ data: unknown[] | Record<string, unknown>,
15
+ filename?: string,
16
+ options?: JsonToCsvOptions
17
+ ): Response;
@@ -0,0 +1,54 @@
1
+ const jtcsv = require('jtcsv');
2
+
3
+ function normalizeFilename(filename) {
4
+ if (!filename || typeof filename !== 'string') {
5
+ return 'export.csv';
6
+ }
7
+ return filename.includes('.') ? filename : `${filename}.csv`;
8
+ }
9
+
10
+ async function parseCsv(request, options = {}) {
11
+ if (!request || typeof request.text !== 'function') {
12
+ throw new Error('parseCsv expects a Request instance');
13
+ }
14
+
15
+ const { fieldName = 'file', ...csvOptions } = options;
16
+ const contentType = request.headers?.get?.('content-type') || '';
17
+ let csvText = null;
18
+
19
+ if (options.formData || contentType.includes('multipart/form-data')) {
20
+ const formData = await request.formData();
21
+ const value = formData.get(fieldName) ?? formData.values().next().value;
22
+ if (value && typeof value.text === 'function') {
23
+ csvText = await value.text();
24
+ } else if (value != null) {
25
+ csvText = String(value);
26
+ }
27
+ } else {
28
+ csvText = await request.text();
29
+ }
30
+
31
+ if (!csvText) {
32
+ throw new Error('No CSV payload found in request');
33
+ }
34
+
35
+ return jtcsv.csvToJson(csvText, csvOptions);
36
+ }
37
+
38
+ function generateCsv(data, filename = 'export.csv', options = {}) {
39
+ const safeName = normalizeFilename(filename);
40
+ const rows = Array.isArray(data) ? data : [data];
41
+ const csv = jtcsv.jsonToCsv(rows, options);
42
+
43
+ return new Response(csv, {
44
+ headers: {
45
+ 'Content-Type': 'text/csv; charset=utf-8',
46
+ 'Content-Disposition': `attachment; filename="${safeName}"`
47
+ }
48
+ });
49
+ }
50
+
51
+ module.exports = {
52
+ parseCsv,
53
+ generateCsv
54
+ };
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@jtcsv/sveltekit",
3
+ "version": "1.0.0",
4
+ "description": "SvelteKit helpers for JTCSV",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "keywords": [
8
+ "sveltekit",
9
+ "csv",
10
+ "json",
11
+ "converter",
12
+ "jtcsv"
13
+ ],
14
+ "author": "Ruslan Fomenko",
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/Linol-Hamelton/jtcsv.git",
19
+ "directory": "plugins/sveltekit"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
23
+ },
24
+ "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/sveltekit#readme",
25
+ "peerDependencies": {
26
+ "jtcsv": "^2.1.3"
27
+ },
28
+ "files": [
29
+ "index.js",
30
+ "index.d.ts",
31
+ "README.md"
32
+ ]
33
+ }
@@ -0,0 +1,22 @@
1
+ # @jtcsv/trpc
2
+
3
+ tRPC helper for JTCSV.
4
+
5
+ ## Install
6
+ ```bash
7
+ npm install @jtcsv/trpc jtcsv
8
+ ```
9
+
10
+ ## Usage
11
+ ```typescript
12
+ import { initTRPC } from '@trpc/server';
13
+ import { z } from 'zod';
14
+ import { createCsvProcedure } from 'jtcsv/trpc';
15
+
16
+ const t = initTRPC.create();
17
+
18
+ export const router = t.router({
19
+ parseCsv: createCsvProcedure(t, z.string(), { delimiter: ',' })
20
+ .mutation(async ({ input }) => ({ parsed: input }))
21
+ });
22
+ ```
@@ -0,0 +1,7 @@
1
+ import type { CsvToJsonOptions } from 'jtcsv';
2
+
3
+ export function createCsvProcedure<TProcedureBuilder>(
4
+ t: { procedure: TProcedureBuilder },
5
+ schema: unknown,
6
+ options?: CsvToJsonOptions
7
+ ): TProcedureBuilder;
@@ -0,0 +1,32 @@
1
+ const jtcsv = require('jtcsv');
2
+
3
+ function extractCsvText(input) {
4
+ if (typeof input === 'string') {
5
+ return input;
6
+ }
7
+ if (input && typeof input === 'object' && typeof input.csv === 'string') {
8
+ return input.csv;
9
+ }
10
+ return null;
11
+ }
12
+
13
+ function createCsvProcedure(t, schema, options = {}) {
14
+ if (!t || !t.procedure) {
15
+ throw new Error('createCsvProcedure expects initTRPC instance');
16
+ }
17
+
18
+ return t.procedure
19
+ .input(schema)
20
+ .use(async ({ input, next }) => {
21
+ const csvText = extractCsvText(input);
22
+ if (!csvText) {
23
+ throw new Error('CSV input must be a string or { csv: string }');
24
+ }
25
+ const parsed = jtcsv.csvToJson(csvText, options);
26
+ return next({ input: parsed });
27
+ });
28
+ }
29
+
30
+ module.exports = {
31
+ createCsvProcedure
32
+ };
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@jtcsv/trpc",
3
+ "version": "1.0.0",
4
+ "description": "tRPC helper for JTCSV CSV parsing",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "keywords": [
8
+ "trpc",
9
+ "csv",
10
+ "json",
11
+ "converter",
12
+ "jtcsv"
13
+ ],
14
+ "author": "Ruslan Fomenko",
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/Linol-Hamelton/jtcsv.git",
19
+ "directory": "plugins/trpc"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/Linol-Hamelton/jtcsv/issues"
23
+ },
24
+ "homepage": "https://github.com/Linol-Hamelton/jtcsv/tree/main/plugins/trpc#readme",
25
+ "peerDependencies": {
26
+ "@trpc/server": "^10.0.0",
27
+ "jtcsv": "^2.1.3"
28
+ },
29
+ "files": [
30
+ "index.js",
31
+ "index.d.ts",
32
+ "README.md"
33
+ ]
34
+ }