ts-edifact
Version:
Edifact parser library
433 lines • 16.4 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InterchangeBuilder = exports.Edifact = exports.RecipientsRef = exports.Receiver = exports.Sender = exports.SyntaxIdentifier = exports.Message = exports.Group = void 0;
const tracker_1 = require("./tracker");
const fs = __importStar(require("fs"));
const edifact_1 = require("./edifact");
const index_1 = require("./index");
class Group {
constructor(name, parent) {
this.data = [];
this.name = name;
this.parent = parent;
}
addSegment(segment) {
this.data.push(segment);
}
addGroup(group) {
this.data.push(group);
}
groupCount() {
let count = 0;
for (const group of this.data) {
if (group instanceof Group) {
count++;
}
}
return count;
}
containsGroup(groupName) {
for (const group of this.data) {
if (group instanceof Group && group.name === groupName) {
return true;
}
}
return false;
}
groupByName(groupName) {
for (const group of this.data) {
if (group instanceof Group && group.name === groupName) {
return group;
}
}
return undefined;
}
}
exports.Group = Group;
class Message {
constructor(data) {
this.header = [];
this.detail = [];
this.summary = [];
this.messageHeader = new edifact_1.MessageHeader(data);
}
addSegment(segment, sectionName) {
this.section(sectionName).push(segment);
}
addGroup(group, sectionName) {
this.section(sectionName).push(group);
}
section(name) {
if (name === "header") {
return this.header;
}
else if (name === "detail") {
return this.detail;
}
else if (name === "summary") {
return this.summary;
}
else {
return this.header.concat(this.detail).concat(this.summary);
}
}
groupCount(sectionName) {
let count = 0;
for (const group of this.section(sectionName)) {
if (group instanceof Group) {
count++;
}
}
return count;
}
containsGroup(groupName, sectionName) {
for (const group of this.section(sectionName)) {
if (group instanceof Group && group.name === groupName) {
return true;
}
}
return false;
}
groupByName(groupName, sectionName) {
for (const group of this.section(sectionName)) {
if (group instanceof Group && group.name === groupName) {
return group;
}
}
return undefined;
}
}
exports.Message = Message;
class SyntaxIdentifier {
constructor(components) {
this.syntaxIdentifer = components[0];
this.version = components[1];
if (components.length >= 3) {
this.serviceCodeListDirectoryVersionNumber = components[2];
}
if (components.length === 4) {
this.charEncoding = components[3];
}
}
}
exports.SyntaxIdentifier = SyntaxIdentifier;
class Participant {
constructor(components) {
this.id = components[0];
if (components.length >= 2) {
this.codeQualifier = components[1];
}
if (components.length >= 3) {
this.internalId = components[2];
}
if (components.length === 4) {
this.internalSubId = components[3];
}
}
}
class Sender extends Participant {
constructor(compnenets) {
super(compnenets);
}
}
exports.Sender = Sender;
class Receiver extends Participant {
constructor(components) {
super(components);
}
}
exports.Receiver = Receiver;
class RecipientsRef {
constructor(components) {
this.password = components[0];
if (components.length === 2) {
this.passwordQualifier = components[1];
}
}
}
exports.RecipientsRef = RecipientsRef;
class Edifact {
constructor(elements) {
this.messages = [];
this.syntaxIdentifier = new SyntaxIdentifier(elements[0]);
this.sender = new Sender(elements[1]);
this.receiver = new Receiver(elements[2]);
this.date = elements[3][0];
this.time = elements[3][1];
this.interchangeNumber = elements[4][0];
if (elements.length >= 6) {
this.recipientsRef = new RecipientsRef(elements[5]);
}
if (elements.length >= 7) {
this.applicationRef = elements[6][0];
}
if (elements.length >= 8) {
this.processingPriorityCode = elements[7][0];
}
if (elements.length >= 9) {
this.ackRequest = parseInt(elements[8][0]);
}
if (elements.length >= 10) {
this.agreementId = elements[9][0];
}
if (elements.length === 11) {
this.testIndicator = parseInt(elements[10][0]);
}
else {
this.testIndicator = 0;
}
}
addMessage(message) {
this.messages.push(message);
}
}
exports.Edifact = Edifact;
class InterchangeBuilder {
constructor(parsingResult, separators, basePath) {
this.stack = [];
this.curSection = "header";
if (!parsingResult || parsingResult.length === 0) {
throw Error("Invalid list of parsed segments provided");
}
let interchange;
for (const segment of parsingResult) {
switch (segment.name) {
case "UNB":
interchange = new Edifact(segment.elements);
break;
case "UNZ":
break;
case "UNT":
this.reset();
break;
default:
if (segment.name === "UNH") {
const message = new Message(segment);
const messageVersion = message.messageHeader.messageIdentifier.messageVersionNumber
+ message.messageHeader.messageIdentifier.messageReleaseNumber;
const messageType = message.messageHeader.messageIdentifier.messageType;
const table = this.getMessageStructureDefForMessage(basePath, messageVersion, messageType);
this.stack = [new tracker_1.Pointer(table, 0)];
this.curSection = "header";
if (interchange) {
interchange.addMessage(message);
}
else {
throw Error("");
}
}
const message = interchange === null || interchange === void 0 ? void 0 : interchange.messages[interchange.messages.length - 1];
if (message) {
const messageVersion = message.messageHeader.messageIdentifier.messageVersionNumber
+ message.messageHeader.messageIdentifier.messageReleaseNumber;
this.accept(segment, message, messageVersion, separators.decimalSeparator);
}
else {
throw Error(`Couldn't process ${segment.name} segment as no message was found.`);
}
}
}
if (interchange) {
this.interchange = interchange;
}
else {
throw Error("Could not generate EDIFACT interchange structure");
}
}
reset() {
this.stack.length = 1;
this.stack[0].position = 0;
this.stack[0].count = 0;
}
accept(segment, obj, version, decimalSeparator) {
let current = this.stack[this.stack.length - 1];
let optionals = [];
let probe = 0;
while (segment.name !== current.content() || current.count === current.repetition()) {
if (Array.isArray(current.content()) && current.count < current.repetition()) {
probe++;
if (!current.mandatory()) {
optionals.push(this.stack.length);
}
current.count++;
current = new tracker_1.Pointer(current.content(), 0);
this.stack.push(current);
}
else {
if (current.mandatory() && current.count === 0) {
if (optionals.length === 0) {
const segName = current.name();
if (segName) {
throw new Error(`A mandatory segment ${current.content()} defined in segment group '${segName}' is missing`);
}
else {
throw new Error(`A mandatory segment ${current.content()} is missing`);
}
}
else {
probe = probe - this.stack.length;
this.stack.length = optionals.pop();
current = this.stack[this.stack.length - 1];
probe = probe + this.stack.length;
}
}
current.position++;
current.count = 0;
const sect = current.section();
if (sect) {
this.curSection = sect;
}
if (current.position === current.array.length) {
this.stack.pop();
current = this.stack[this.stack.length - 1];
if (this.stack.length === 0) {
throw new Error(`Reached the end of the segment table while processing segment ${segment.name}`);
}
if (probe === 0 && current.count < current.repetition()) {
probe++;
optionals = [this.stack.length];
current.count++;
current = new tracker_1.Pointer(current.content(), 0);
this.stack.push(current);
}
else {
if (!current.mandatory() || current.count > 1) {
optionals.pop();
}
probe = probe > 0 ? probe - 1 : 0;
current.count = current.repetition();
}
}
}
}
current.count += 1;
if (this.stack.length > 1) {
let curObj = obj;
for (let idx = 0; idx < this.stack.length; idx++) {
const pointer = this.stack[idx];
const groupName = pointer.name();
if (groupName) {
if (!curObj.containsGroup(groupName)) {
const group = new Group(groupName, curObj);
curObj.addGroup(group, this.curSection);
curObj = group;
}
else {
const group = curObj.groupByName(groupName);
if (group) {
curObj = group;
if (pointer.count > 1) {
if (!(group.data[0] instanceof Group)) {
const subGroup = new Group("0", group);
for (const data of group.data) {
if (data instanceof Group) {
subGroup.addGroup(data);
}
else {
subGroup.addSegment(data);
}
}
group.data = [];
group.addGroup(subGroup);
}
const subGroup = group.groupByName(`${pointer.count - 1}`);
if (subGroup) {
curObj = subGroup;
}
else {
const sg = new Group(`${group.groupCount()}`, group);
group.addGroup(sg);
curObj = sg;
}
}
}
else {
throw Error(`Could not find group ${groupName} as part of ${curObj.toString()}`);
}
}
}
else {
const seg = (0, edifact_1.toSegmentObject)(segment, version, decimalSeparator);
curObj.addSegment(seg, this.curSection);
}
}
}
else {
if (segment.name !== "UNH") {
const seg = (0, edifact_1.toSegmentObject)(segment, version, decimalSeparator);
obj.addSegment(seg, this.curSection);
}
}
}
getMessageStructureDefForMessage(basePath, messageVersion, messageType) {
let path = basePath + messageVersion + "_" + messageType + ".struct.json";
if (fs.existsSync(path)) {
return this.readFileAsMessageStructure(path);
}
else {
path = basePath + messageType + "struct.json";
if (fs.existsSync(path)) {
return this.readFileAsMessageStructure(path);
}
else {
switch (messageType) {
case "APERAK":
return index_1.APERAK;
case "AUTHOR":
return index_1.AUTHOR;
case "BALANC":
return index_1.BALANC;
case "DESADV":
return index_1.DESADV;
case "GENRAL":
return index_1.GENRAL;
case "IFTMIN":
return index_1.IFTMIN;
case "INVOIC":
return index_1.INVOIC;
case "INVRPT":
return index_1.INVRPT;
case "ORDERS":
return index_1.ORDERS;
case "OSTENQ":
return index_1.OSTENQ;
case "OSTRPT":
return index_1.OSTRPT;
case "PARTIN":
return index_1.PARTIN;
case "TAXCON":
return index_1.TAXCON;
case "VATDEC":
return index_1.VATDEC;
default:
throw new Error(`Could not find message definiton for message type '${messageType}' of version '${messageVersion}'`);
}
}
}
}
readFileAsMessageStructure(path) {
const data = fs.readFileSync(path, { encoding: "utf-8" });
return JSON.parse(data);
}
}
exports.InterchangeBuilder = InterchangeBuilder;
//# sourceMappingURL=interchangeBuilder.js.map
;