ts-edifact
Version:
Edifact parser library
202 lines • 8.51 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.UNECEStructurePageParser = void 0;
const unecePageParser_1 = require("./unecePageParser");
var State;
(function (State) {
State["initial"] = "initial";
State["messageStructureStart"] = "messageStructureStart";
State["messageStructureEnd"] = "messageStructureEnd";
State["headerSection"] = "headerSection";
State["detailSection"] = "detailSection";
State["summarySection"] = "summarySection";
State["beforeDetailSection"] = "beforeDetailSection";
State["segmentPosition"] = "segmentPosition";
State["segmentGroup"] = "segmentGroup";
State["segmentName"] = "segmentName";
State["segmentDescription"] = "segmentDescription";
})(State || (State = {}));
const SM_DEFINITION = {
initial: State.initial,
transitions: [
{ from: State.initial, to: State.messageStructureStart },
{ from: State.messageStructureStart, to: State.headerSection },
{ from: State.messageStructureStart, to: State.segmentPosition },
{ from: State.headerSection, to: State.segmentPosition },
{ from: State.detailSection, to: State.segmentPosition },
{ from: State.summarySection, to: State.segmentPosition },
{ from: State.segmentPosition, to: State.segmentGroup },
{ from: State.segmentPosition, to: State.messageStructureEnd },
{ from: State.segmentGroup, to: State.segmentName },
{ from: State.segmentGroup, to: State.segmentPosition },
{ from: State.segmentName, to: State.segmentDescription },
{ from: State.segmentDescription, to: State.segmentPosition },
{ from: State.segmentDescription, to: State.detailSection },
{ from: State.segmentDescription, to: State.summarySection }
]
};
class UNECEStructurePageParser extends unecePageParser_1.UNECEPageParser {
constructor(spec) {
super(SM_DEFINITION);
this._spec = spec;
this.segmentNames = [];
}
setupHandler() {
const helper = super.setupHandler();
let index = 0;
const stack = [];
const resetStack = () => {
for (; index > 0; index--) {
stack.pop();
}
};
let isSegmentGroupEnd = false;
let section;
let name;
stack.push(this.spec.messageStructureDefinition);
helper.onText = (text) => {
switch (this.sm.state) {
case State.initial:
if (text.includes('Message structure')) {
this.sm.transition(State.messageStructureStart);
}
break;
case State.messageStructureStart:
if (text.includes('HEADER SECTION')) {
this.sm.transition(State.headerSection);
section = 'header';
this.sm.transition(State.segmentPosition);
}
break;
case State.segmentPosition:
if (text.match(/[0-9]{4}/g)) {
this.sm.transition(State.segmentGroup);
}
else {
this.sm.transition(State.messageStructureEnd);
}
break;
case State.segmentGroup:
if (text.includes('Segment group')) {
isSegmentGroupEnd = false;
const group = this.parseSegmentGroup(section, text);
const level = this.parseSegmentGroupLevel(text);
const delta = level - index;
if (delta <= 0) {
for (let i = 0; i < (delta * -1 + 1); i++) {
stack.pop();
index--;
}
}
stack[index].push(group);
stack.push(group.content);
index++;
section = undefined;
this.sm.transition(State.segmentPosition);
}
else {
if (isSegmentGroupEnd) {
resetStack();
}
this.sm.transition(State.segmentName);
}
break;
case State.segmentName:
name = text;
this.addSegmentName(name);
this.sm.transition(State.segmentDescription);
break;
case State.segmentDescription: {
const item = this.parseSegment(name, section, text);
stack[index].push(item);
isSegmentGroupEnd = this.isSegmentGroupEnd(text);
const detailSection = text.includes('DETAIL SECTION');
const summarySection = text.includes('SUMMARY SECTION');
if (detailSection || summarySection) {
resetStack();
if (detailSection) {
section = 'detial';
this.sm.transition(State.detailSection);
}
else {
section = 'summary';
this.sm.transition(State.summarySection);
}
}
this.sm.transition(State.segmentPosition);
break;
}
case State.messageStructureEnd: break;
default: this.throwInvalidParserState(this.sm.state);
}
};
helper.onOpenTag = name => {
if (this.sm.state === State.messageStructureStart && name === 'a') {
this.sm.transition(State.segmentPosition);
}
};
return helper;
}
addSegmentName(name) {
const excludeSegmentNames = ['UNH', 'UNS', 'UNT'];
if (!excludeSegmentNames.includes(name) && !this.segmentNames.includes(name)) {
this.segmentNames.push(name);
}
}
parseSegmentGroup(section, descriptionString) {
const regex = /^.* (Segment group \d*).*\s*([M|C])\s*(\d*).*/g;
const matches = regex.exec(descriptionString);
if (!matches) {
throw new Error('Invalid segment description string');
}
const name = matches[1];
const mandatoryString = matches[2];
const repetitionString = matches[3];
return {
name,
content: [],
mandatory: mandatoryString === 'M',
repetition: Number.parseInt(repetitionString),
data: undefined,
section: section || undefined
};
}
parseSegment(name, section, descriptionString) {
const regex = /^([a-zA-Z /\\-]*)\s*?([M|C])\s*?([0-9]*?)([^0-9]*)$/g;
const matches = regex.exec(descriptionString);
if (!matches) {
throw new Error(`${name}: Invalid segment description string: ${descriptionString}`);
}
const mandatoryString = matches[2];
const repetitionString = matches[3];
return {
content: name,
mandatory: mandatoryString === 'M',
repetition: Number.parseInt(repetitionString),
data: undefined,
section: section || undefined
};
}
parseSegmentGroupLevel(descriptionString) {
const regex = /^.*[0-9]+([^0-9]*)$/g;
const matches = regex.exec(descriptionString);
if (!matches) {
throw new Error('Invalid segment description string');
}
const levelString = Array.from(matches[1]).reverse().join('');
let normalization = 0;
if (levelString.charCodeAt(0) !== 10) {
console.warn(`Unrecognized character in level string: ${levelString[0]} (${levelString.charCodeAt(0)})`);
}
else if (levelString.charCodeAt(1) === 13) {
normalization = 1;
}
return levelString.indexOf('Ŀ') - normalization;
}
isSegmentGroupEnd(descriptionString) {
const regex = /\d+�+/g;
return !!regex.exec(descriptionString);
}
}
exports.UNECEStructurePageParser = UNECEStructurePageParser;
//# sourceMappingURL=uneceStructurePageParser.js.map
;