]> git.ardis.lu - csvio/commitdiff
Refactor createCSVDenormalizationStream to CSVDenormalizer
authorArdis Lu <ardisglu@gmail.com>
Sun, 19 Jan 2025 07:52:59 +0000 (23:52 -0800)
committerArdis Lu <ardisglu@gmail.com>
Sun, 19 Jan 2025 07:52:59 +0000 (23:52 -0800)
README.md
examples/README.md
examples/ex4.js
src/index.js
src/normalization.js
test/normalization.test.js

index e11b45030e12cf30b2432b0b2d27c75c2e55b9a6..80115196f1b51ba0d24e89ab65cf26076eda7e88 100644 (file)
--- a/README.md
+++ b/README.md
@@ -107,7 +107,7 @@ const writableStream = new CSVWriter('./data/example-out.csv');
 
 In addition to the core API, optional utilities are provided to address common CSV transformation tasks.
 
-### `CSVNormalizer` and `createCSVDenormalizationStream`
+### `CSVNormalizer` and `CSVDenormalizer`
 
 `TransformStream`s to parse CSVs that have been mangled by spreadsheet programs such as Excel.
 
index c27eddd2bf5497d48582dc5ba31c2dc2bfc5255f..e9fec20ac3deb2a4ddc387bf9bdd56af366b5242 100644 (file)
@@ -16,7 +16,7 @@ node ./examples/ex1.js
 
 [Example 3: Chaining multiple transformations](./ex3.js)
 
-[Example 4: Using `createCSVNormalizationStream` and `createCSVDenormalizationStream`](./ex4.js)
+[Example 4: Using `CSVNormalizer` and `CSVDenormalizer`](./ex4.js)
 
 [Example 5: Handling an irregularly-shaped CSV file](./ex5.js)
 
index 717b2fefbf84c7476914b64c1bbc961ae665c656..072edc58e41c7b78e320e9e686644b7e18d58560 100644 (file)
@@ -1,4 +1,4 @@
-// ## Example 4: Using `CSVNormalizer` and `createCSVDenormalizationStream`
+// ## Example 4: Using `CSVNormalizer` and `CSVDenormalizer`
 // 
 // These functions fix common CSV data mangling caused by Excel. In `ex4-in.csv`:
 // - The "Index" column has been mangled into Excel's "Accounting" format
@@ -6,9 +6,9 @@
 // - The "Join Timestamp" column has been mangled into a number
 // - There are trailing empty rows after deleting excess data from the CSV
 // `CSVNormalizer` performs transformations to un-mangle the above using only a declaration of the header names and data types.
-// `createCSVDenormalizationStream` converts the data stream back into a CSV row.
+// `CSVDenormalizer` converts the data stream back into a CSV row.
 
-import { CSVReader, CSVWriter, CSVNormalizer, createCSVDenormalizationStream } from '../src/index.js';
+import { CSVReader, CSVWriter, CSVNormalizer, CSVDenormalizer } from '../src/index.js';
 
 // The order of items in `headers` is significant, it determines the order of the output CSV columns.
 // If an input column is not provided in `headers`, the column is removed from the output CSV.
@@ -32,5 +32,5 @@ const headers = [
 
 await new CSVReader(new URL('./data/ex4-in.csv', import.meta.url))
   .pipeThrough(new CSVNormalizer(headers))
-  .pipeThrough(createCSVDenormalizationStream())
+  .pipeThrough(new CSVDenormalizer())
   .pipeTo(new CSVWriter(new URL('./data/ex4-out.csv', import.meta.url)));
\ No newline at end of file
index b5c41383bc199ecc1295b71557eb45a1f6ec8a3a..22441a5ac65ceff32045d4c826b2da3f59aaf2e4 100644 (file)
@@ -1,2 +1,2 @@
 export { CSVReader, CSVTransformer, CSVWriter } from './core.js';
-export { CSVNormalizer, createCSVDenormalizationStream } from './normalization.js';
+export { CSVNormalizer, CSVDenormalizer } from './normalization.js';
index 6b7811130d42f413535cf313170dc2aae49059e2..0c463aa1253550373b5b90f3f79f5c81f00f9a43 100644 (file)
@@ -286,20 +286,21 @@ export class CSVNormalizer extends TransformStream {
 }
 
 /**
- * Create a `TransformStream` to transform a `CSVNormalizerRow` into an array that can be converted to CSV data.
- * 
- * @returns {TransformStream} A `TransformStream` where each chunk is one row of the CSV file.
+ * A `TransformStream` to transform a `CSVNormalizerRow` into an array that can be converted to CSV data.
+ * @extends TransformStream
  */
-export function createCSVDenormalizationStream() {
-  let firstRow = true;
-  return new TransformStream({
-    transform(chunk, controller) {
-      const row = JSON.parse(chunk);
-      if (firstRow) {
-        firstRow = false;
-        controller.enqueue(JSON.stringify(row.map(f => f.displayName)));
+export class CSVDenormalizer extends TransformStream {
+  constructor() {
+    let firstRow = true;
+    super({
+      transform(chunk, controller) {
+        const row = JSON.parse(chunk);
+        if (firstRow) {
+          firstRow = false;
+          controller.enqueue(JSON.stringify(row.map(f => f.displayName)));
+        }
+        controller.enqueue(JSON.stringify(row.map(f => f.value)));
       }
-      controller.enqueue(JSON.stringify(row.map(f => f.value)));
-    }
-  });
+    });
+  }
 }
index 34f734dc0cc93b5db9c20b9c88285b2a83890e03..dba486a39cc90ec6d9d6302ab1608e9a957c2c3d 100644 (file)
@@ -3,7 +3,7 @@ import { deepStrictEqual } from 'node:assert/strict';
 
 import { csvStreamEqual, csvStreamEqualWritable, createCSVMockStream } from './utils.js';
 import { CSVReader } from '../src/core.js';
-import { toCamelCase, expandScientificNotation, fixExcelNumber, fixExcelBigInt, fixExcelDate, CSVNormalizer, createCSVDenormalizationStream } from '../src/normalization.js';
+import { toCamelCase, expandScientificNotation, fixExcelNumber, fixExcelBigInt, fixExcelDate, CSVNormalizer, CSVDenormalizer } from '../src/normalization.js';
 
 suite('toCamelCase', { concurrency: true }, () => {
   test('does not modify strings already in camelCase', { concurrency: true }, () => {
@@ -179,7 +179,7 @@ suite('CSVNormalizer', { concurrency: true }, () => {
         { name: 'columnA', type: 'string' },
         { name: 'columnB', type: 'string' }
       ]))
-      .pipeThrough(createCSVDenormalizationStream())
+      .pipeThrough(new CSVDenormalizer())
       .pipeTo(csvStreamEqualWritable([
         ['columnA', 'columnB'],
         ['a', 'b']
@@ -195,7 +195,7 @@ suite('CSVNormalizer', { concurrency: true }, () => {
         { name: 'columnB', type: 'string' },
         { name: 'columnC', type: 'string' }
       ]))
-      .pipeThrough(createCSVDenormalizationStream())
+      .pipeThrough(new CSVDenormalizer())
       .pipeTo(csvStreamEqualWritable([
         ['columnA', 'columnB', 'columnC'],
         ['a', 'b', 'c']
@@ -210,7 +210,7 @@ suite('CSVNormalizer', { concurrency: true }, () => {
         { name: 'columnA', type: 'string', displayName: 'Column A' },
         { name: 'columnB', type: 'string', displayName: 'Column B' }
       ]))
-      .pipeThrough(createCSVDenormalizationStream())
+      .pipeThrough(new CSVDenormalizer())
       .pipeTo(csvStreamEqualWritable([
         ['Column A', 'Column B'],
         ['a', 'b']
@@ -229,7 +229,7 @@ suite('CSVNormalizer', { concurrency: true }, () => {
         { name: 'columnA', type: 'string' },
         { name: 'columnB', type: 'string' }
       ]))
-      .pipeThrough(createCSVDenormalizationStream())
+      .pipeThrough(new CSVDenormalizer())
       .pipeTo(csvStreamEqualWritable([
         ['columnA', 'columnB'],
         ['a', 'b']
@@ -244,7 +244,7 @@ suite('CSVNormalizer', { concurrency: true }, () => {
         { name: 'columnA', type: 'abc' },
         { name: 'columnB', type: 'def' }
       ]))
-      .pipeThrough(createCSVDenormalizationStream())
+      .pipeThrough(new CSVDenormalizer())
       .pipeTo(csvStreamEqualWritable([
         ['columnA', 'columnB'],
         ['a', 'b']
@@ -252,7 +252,7 @@ suite('CSVNormalizer', { concurrency: true }, () => {
   });
 });
 
-suite('CSVNormalizer and createCSVDenormalizationStream end-to-end', { concurrency: true }, () => {
+suite('CSVNormalizer and CSVDenormalizer end-to-end', { concurrency: true }, () => {
   test('can normalize', { concurrency: true }, async () => {
     const headers = [
       { name: 'stringCol', displayName: 'String Column', type: 'string', defaultValue: 'N/A' },
@@ -262,7 +262,7 @@ suite('CSVNormalizer and createCSVDenormalizationStream end-to-end', { concurren
     ]
     const stream = new CSVReader('./test/data/normalization.csv')
       .pipeThrough(new CSVNormalizer(headers))
-      .pipeThrough(createCSVDenormalizationStream());
+      .pipeThrough(new CSVDenormalizer());
     await csvStreamEqual(stream, [
       ['String Column', 'Number Column', 'BigInt Column', 'Date Column'],
       ['abc ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ', 123456789.123456, '1000000000000000000', '2024-01-01T00:00:00.000Z'],
This page took 0.07794 seconds and 4 git commands to generate.