]> git.ardis.lu - csvio/commitdiff
Add `.source` property for `FieldMap`
authorArdis Lu <ardisglu@gmail.com>
Sun, 2 Nov 2025 05:05:52 +0000 (22:05 -0700)
committerArdis Lu <ardisglu@gmail.com>
Sun, 2 Nov 2025 05:05:52 +0000 (22:05 -0700)
This property is useful when there is no other variable set to access the underlying row (e.g., `.toFieldMap` was called with a literal object).

src/normalization.js
test/normalization.test.js

index 04cff95cd0b483e34f5e9abfc9f2e1be9ad68b06..e22c41168b97d2e01b8921404f7fcf38cc630f5d 100644 (file)
@@ -339,6 +339,12 @@ export class CSVNormalizer extends TransformStream {
     return object;
   }
 
+  /**
+   * @typedef {Object} FieldMapExtensions
+   * @property {Array<CSVNormalizerField>} source The original CSV row object that was passed to `.toFieldMap` to
+   * create the `FieldMap` object.
+   */
+
   /**
    * Create a subset of the `Map` interface to get and set the `value` of a field using its `name`.
    * 
@@ -354,14 +360,16 @@ export class CSVNormalizer extends TransformStream {
    * - `.clear()`
    * - `.size`
    * 
-   * All other methods are unsupported. For more advanced usage, use the underlying `row` object directly.
+   * All other `Map` methods are unsupported.
    * 
-   * The `displayName` and `emptyField` values of a field cannot be accessed from the `Map`.
+   * The `displayName` and `emptyField` values of a field cannot be accessed from the `Map`. Calling `.set()` with a
+   * `name` that is not in the row will push a new field to the row.
    * 
-   * Calling `.set()` with a `name` that is not in the row will push a new field to the row.
+   * For more advanced usage, use the underlying `row` object directly. You can access the underlying `row` object by
+   * calling the `.source` property.
    * @param {Array<CSVNormalizerField>} row A normalized CSV row.
-   * @returns {Pick<Map<string,any>,'get'|'set'|'has'|'delete'|'clear'|'size'>} A `Proxy` over a `Map` object with keys
-   * set to the `name` of each field in the row.
+   * @returns {Pick<Map<string,any>,'get'|'set'|'has'|'delete'|'clear'|'size'>&FieldMapExtensions}} A `Proxy`
+   * over a `Map` object with keys set to the `name` of each field in the row.
    */
   static toFieldMap(row) {
     const map = new Map();
@@ -407,6 +415,9 @@ export class CSVNormalizer extends TransformStream {
             target.clear();
           }
         }
+        if (prop === 'source') {
+          return row;
+        }
       }
     });
   }
index 846eeea4c9bb758a390a830de1ad0a7fb9a360b8..268b52ed47e1c3cd76d39dbef783a83be020957b 100644 (file)
@@ -275,6 +275,15 @@ suite('CSVNormalizer.toFieldMap', { concurrency: true }, () => {
     const map = CSVNormalizer.toFieldMap(row);
     deepStrictEqual(map.size, 1);
   });
+  test('has a .source property to access the underlying row', { concurrency: true }, async () => {
+    const row = [{ name: 'a', value: 1 }];
+    const map = CSVNormalizer.toFieldMap(row);
+    ok(map.source === row); // Intentionally comparing by reference, do not use deepStrictEqual
+    row.push({ name: 'b', value: 2 });
+    ok(map.source === row);
+    map.source.push({ name: 'c', value: 3 });
+    ok(map.source === row);
+  });
 });
 
 suite('CSVNormalizer.from', { concurrency: true }, () => {
This page took 0.039302 seconds and 4 git commands to generate.