[![view on npm](http://img.shields.io/npm/v/simple-edifact-parser.svg)](https://www.npmjs.org/package/simple-edifact-parser)
[![npm module downloads per month](http://img.shields.io/npm/dm/simple-edifact-parser.svg)](https://www.npmjs.org/package/simple-edifact-parser)

# node-simple-edifact-parser

Currently supported functionality:

* An ES6 streaming parser reading UN/EDIFACT messages.
* Provide your own event listeners to get the parser to do something useful.
* Construct structured javascript objects from UN/EDIFACT messages.
* Support for the UNA header and custom separators.

This library further intends to support:

* Out of the box support for envelopes.

This library is based on the work of Tom De Caluwé for the node-edifact library.

## Usage

This example parses a document and translates it to a javascript array `result`
containing segments. Each segment is an object containing a `name` and an
`elements` array. An element is an array of components.

```javascript
var Parser = require('edifact/parser.js');

var doc = ...;

var parser = new Parser(validator);

// Parsed segments will be collected in the result array.
var result = [], elements, components;

parser.on('opensegment', function (segment) {
  // Started a new segment.
  elements = [];
  result.push({ name: segment, elements: elements });
});

parser.on('element', function () {
  // Parsed a new element.
  components = [];
  elements.push(components);
});

parser.on('component', function (data) {
  // Got a new component.
  components.push(value);
});

parser.on('closesegment', function () {
  // Closed a segment.
});

parser.write(doc)
parser.end();
```

## Installation

The module can be installed through:

```shell
npm install simple-edifact-parser
```

Its only dependency is the node `events` library. Keep in mind that this is an
ES6 library. It currently can be used with node 6.4 or higher. A suite of tests
is included which can be run with the `jasmine-es6` package.

## Overview

This module is built around a central `Parser` class which provides the core
UN/EDIFACT parsing functionality. It exposes two methods, the `write()` method
to write some data to the parser and the `end()` method to close an EDI
interchange. Data read by the parser can be read by using hooks which will be
called on specific parsing events.

### Configuring the parser

The `Parser` class currently supports any of the `UNOA`, `UNOB`, `UNOC`, `UNOY`
`UNOW` and `UCS2` encoding levels. Furthermore, the parser will read any custom
delimiters from the `UNA` header. If such a header is not present in the
document, the delimiters can also be configured manually. The delimiters should
be specified using their character codes. An example:

```javascript
let parser = new Parser();

parser.encoding('UNOC');
parser.configure({
  segmentTerminator: 39,
  dataElementSeparator: 43,
  componentDataSeparator: 58,
  decimalMark: 46,
  releaseCharacter: 63,
});
```

### Parsing events

The parser can be used by listening to the following events:

| Event | Description |
| ----: | :---------- |
| `opensegment` | A new segment is started. The name of the segment is passed as the argument. |
| `element` | A new element is added. This only marks the start of the element, the data will follow through the `component` events. |
| `component` | A component is added to the element. The data is passed on as an argument. |
| `closesegment` | The current segment is terminated. |

For all textual fields the data will be passed on literally to the `component`
event handler.

### Converting EDIFACT to JSON

While the `Parser` class offers a flexible option to write your own EDIFACT
applications, you might only be looking for an easy way read EDIFACT documents.
The `Reader` class offers an easy to use interface:

```javascript
let reader = new Reader({ autoDetectEncoding: true });
let result = reader.parse(document);
```

The `parse()` method returns an array of segments. Each segment is an object
containing a segment `name` and the list of `elements` as an array of arrays
with the actual component data.

### Performance

If performance is critical the event callbacks can also be directly defined as
methods on the `Parser` instance. Defining an event callback `on('opensegment',
callback)` then becomes:

```javascript
let parser = new Parser();
let callback = function (segment) { ... };

parser.onopensegment = callback;
```

Keep in mind that this avoids any `opensegment` events to be produced and as
such, also its associated overhead.

## Classes

| Class | Description |
| ----: | :---------- |
| [Parser](#Parser) | The `Parser` class encapsulates an online parsing algorithm. By itself it doesn't do anything useful, however the parser can be extended through several event callbacks. |
| [Reader](#Reader) | The `Reader` offers a fast an easy to use interface to convert EDIFACT messages to a JSON structure. |

## Reference

<a name="Parser"></a>
### Parser

A parser capable of accepting data formatted as an UN/EDIFACT interchange.:

```
new Parser()
```

| Function | Description |
| -------: | :---------- |
| `configure(config)` | Configure any custom delimiters |
| `encoding(level)` | Set one of the predefined encoding levels |
| `on(event,callback)` | Add a listener for a specific event. The event can be any of `opensegment`, `element`, `component` and `closesegment` |
| `write(chunk)` | Write a chunk of data to the parser |
| `end()` | Terminate the EDI interchange |

<a name="Parser"></a>
### Reader

The `Reader` offers a fast and easy to use interface to convert EDIFACT messages
to a JSON structure. Furthermore, the `Reader` class can also autodetect the
message encoding (this feature can be turned off by passing
`autoDetectEncoding: false` as an option to the constructor).

```
new Reader(options)
```

| Function | Description |
| -------: | :---------- |
| `parse(document)` | Parse a document and return the result as an array of segments. |
