433 lines
16 KiB
JavaScript
433 lines
16 KiB
JavaScript
"use strict";
|
|
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
|