ts-edifact
Version:
Edifact parser library
363 lines • 13.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidatorImpl = exports.NullValidator = exports.ValidatorStates = exports.Dictionary = void 0;
class Dictionary {
constructor(data) {
this.entries = {};
if (data) {
for (const key in data) {
if (key !== "") {
this.add(key, data[key]);
}
}
}
}
contains(key) {
if (Object.prototype.hasOwnProperty.call(this.entries, key)) {
return true;
}
return false;
}
get(key) {
if (this.contains(key)) {
return this.entries[key];
}
return undefined;
}
keys() {
return Object.keys(this.entries);
}
add(key, value) {
this.entries[key] = value;
return value;
}
length() {
return this.keys().length;
}
}
exports.Dictionary = Dictionary;
var ValidatorStates;
(function (ValidatorStates) {
ValidatorStates[ValidatorStates["NONE"] = 0] = "NONE";
ValidatorStates[ValidatorStates["SEGMENTS"] = 1] = "SEGMENTS";
ValidatorStates[ValidatorStates["ELEMENTS"] = 2] = "ELEMENTS";
ValidatorStates[ValidatorStates["ALL"] = 3] = "ALL";
ValidatorStates[ValidatorStates["ENTER"] = 4] = "ENTER";
ValidatorStates[ValidatorStates["ENABLE"] = 5] = "ENABLE";
})(ValidatorStates = exports.ValidatorStates || (exports.ValidatorStates = {}));
class NullValidator {
onOpenSegment() { }
onElement() { }
onOpenComponent() { }
onCloseComponent() { }
onCloseSegment() { }
disable() { }
enable() { }
define() { }
format() { return undefined; }
}
exports.NullValidator = NullValidator;
class ValidatorImpl {
constructor(throwOnMissingDefinitions = false) {
this.segments = new Dictionary();
this.elements = new Dictionary();
this.formats = new Dictionary();
this.counts = {
segment: 0,
element: 0,
component: 0
};
this.segment = undefined;
this.element = undefined;
this.component = undefined;
this.required = 0;
this.minimum = 0;
this.maximum = 0;
this.errors = {
invalidData: function (element, msg) {
return new Error(`Could not accept data on element ${element}: ${msg}`);
},
invalidFormatString: function (formatString) {
return new Error("Invalid format string " + formatString);
},
countError: function (type, name, definition, count) {
let array;
let start = type + " " + name;
let end;
let length = 0;
if (type === "Segment") {
array = "elements";
const entry = definition;
length = entry.elements.length;
}
else {
array = "components";
const entry = definition;
length = entry.components.length;
}
if (count < definition.requires) {
start += " only";
end = ` but requires at least ${definition.requires}`;
}
else {
end = ` but accepts at most ${length}`;
}
return new Error(start + ` got ${count} ` + array + end);
},
missingElementStart: function (segment) {
const message = `Active open element expected on segment ${segment}`;
return new Error(message);
},
missingElementDefinition: function (element) {
const message = `No definition found for element ${element}`;
return new Error(message);
},
missingSegmentStart: function (segment, throwOnMissingDefinitions) {
if (!throwOnMissingDefinitions) {
return undefined;
}
let name;
if (segment) {
name = "'" + segment + "'";
}
else {
name = "''";
}
return new Error(`Active open segment ${name} expected. Found none`);
},
missingSegmentDefinition: function (segment, throwOnMissingDefinitions) {
if (throwOnMissingDefinitions) {
return new Error(`No segment definition found for segment name ${segment}`);
}
else {
console.warn(`No segment definition found for segment name ${segment}`);
return undefined;
}
}
};
this.state = ValidatorStates.ALL;
this.throwOnMissingDefinitions = throwOnMissingDefinitions;
}
disable() {
this.state = ValidatorStates.NONE;
}
enable() {
this.state = ValidatorStates.SEGMENTS;
}
define(definitions) {
for (const key of definitions.keys()) {
const entry = definitions.get(key);
if (entry && Object.prototype.hasOwnProperty.call(entry, "elements")) {
this.segments.add(key, entry);
}
if (entry && Object.prototype.hasOwnProperty.call(entry, "components")) {
this.elements.add(key, entry);
}
}
}
format(formatString) {
if (this.formats.contains(formatString)) {
return this.formats.get(formatString);
}
else {
let parts;
if ((parts = /^(a|an|n)(\.\.)?([1-9][0-9]*)?$/.exec(formatString))) {
const max = parseInt(parts[3]);
const min = parts[2] === ".." ? 0 : max;
let alpha = false;
let numeric = false;
switch (parts[1]) {
case "a":
alpha = true;
break;
case "n":
numeric = true;
break;
case "an":
alpha = true;
numeric = true;
break;
}
return this.formats.add(formatString, { alpha: alpha, numeric: numeric, minimum: min, maximum: max });
}
else {
throw this.errors.invalidFormatString(formatString);
}
}
}
onOpenSegment(segment) {
switch (this.state) {
case ValidatorStates.ALL:
case ValidatorStates.ELEMENTS:
case ValidatorStates.SEGMENTS:
case ValidatorStates.ENABLE:
if ((this.segment = this.segments.get(segment))) {
this.state = ValidatorStates.ELEMENTS;
}
else {
const error = this.errors.missingSegmentDefinition(segment, this.throwOnMissingDefinitions);
if (error) {
throw error;
}
}
}
this.counts.segment += 1;
this.counts.element = 0;
}
onElement() {
let name;
switch (this.state) {
case ValidatorStates.ALL:
if (this.segment === undefined) {
const error = this.errors.missingSegmentStart(undefined, this.throwOnMissingDefinitions);
if (error) {
throw error;
}
else {
return;
}
}
name = this.segment.elements[this.counts.element];
if (this.element === undefined) {
throw this.errors.missingElementStart(name);
}
if (this.counts.component < this.element.requires || this.counts.component > this.element.components.length) {
throw this.errors.countError("Element", name, this.element, this.counts.component);
}
case ValidatorStates.ENTER:
case ValidatorStates.ELEMENTS:
if (this.segment === undefined) {
const error = this.errors.missingSegmentStart(undefined, this.throwOnMissingDefinitions);
if (error) {
throw error;
}
else {
return;
}
}
const key = this.segment.elements[this.counts.element];
if ((this.element = this.elements.get(key))) {
this.state = ValidatorStates.ALL;
}
else {
this.state = ValidatorStates.ELEMENTS;
if (this.throwOnMissingDefinitions) {
throw this.errors.missingElementDefinition(key);
}
}
}
this.counts.element += 1;
this.counts.component = 0;
}
onOpenComponent(buffer) {
if (this.segment === undefined) {
const error = this.errors.missingSegmentStart(undefined, this.throwOnMissingDefinitions);
if (error) {
throw error;
}
else {
return;
}
}
switch (this.state) {
case ValidatorStates.ALL:
const name = this.segment.elements[this.counts.element];
if (this.element === undefined) {
throw this.errors.missingElementStart(name);
}
this.component = this.format(this.element.components[this.counts.component]);
if (this.component === undefined) {
return;
}
this.required = this.element.requires;
this.minimum = this.component.minimum;
this.maximum = this.component.maximum;
if (this.component.alpha) {
if (this.component.numeric) {
buffer.alphanumeric();
}
else {
buffer.alpha();
}
}
else {
if (this.component.numeric) {
buffer.numeric();
}
else {
buffer.alphanumeric();
}
}
break;
default:
buffer.alphanumeric();
}
this.counts.component += 1;
}
onCloseComponent(buffer) {
let length;
switch (this.state) {
case ValidatorStates.ALL:
length = buffer.length();
let name;
if (this.segment) {
name = this.segment.elements[this.counts.element];
}
else {
const error = this.errors.missingSegmentStart(this.segment, this.throwOnMissingDefinitions);
if (error) {
throw error;
}
else {
return;
}
}
if (this.required >= this.counts.component || length > 0) {
if (length < this.minimum) {
throw this.errors.invalidData(name, `'${buffer.content()}' length is less than minimum length ${this.minimum}`);
}
else if (length > this.maximum) {
throw this.errors.invalidData(name, `'${buffer.content()} exceeds maximum length ${this.maximum}`);
}
}
}
}
onCloseSegment(segment) {
let name;
switch (this.state) {
case ValidatorStates.ALL:
if (this.segment === undefined) {
const error = this.errors.missingSegmentStart(segment, this.throwOnMissingDefinitions);
if (error) {
throw error;
}
else {
return;
}
}
if (this.element === undefined) {
throw this.errors.missingElementStart(segment);
}
if (this.counts.component < this.element.requires || this.counts.component > this.element.components.length) {
name = this.segment.elements[this.counts.element];
throw this.errors.countError("Element", name, this.element, this.counts.component);
}
case ValidatorStates.ELEMENTS:
if (this.segment === undefined) {
const error = this.errors.missingSegmentStart(segment, this.throwOnMissingDefinitions);
if (error) {
throw error;
}
else {
return;
}
}
if (this.counts.element < this.segment.requires || this.counts.element > this.segment.elements.length) {
name = segment;
throw this.errors.countError("Segment", name, this.segment, this.counts.element);
}
}
}
}
exports.ValidatorImpl = ValidatorImpl;
//# sourceMappingURL=validator.js.map
;