massbank 0.0.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -5
- package/lib/index.d.ts +4 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -5
- package/lib/index.js.map +1 -1
- package/lib/parser/exceptions.d.ts +9 -0
- package/lib/parser/exceptions.d.ts.map +1 -0
- package/lib/parser/exceptions.js +17 -0
- package/lib/parser/exceptions.js.map +1 -0
- package/lib/parser/field-parsers.d.ts +53 -0
- package/lib/parser/field-parsers.d.ts.map +1 -0
- package/lib/parser/field-parsers.js +218 -0
- package/lib/parser/field-parsers.js.map +1 -0
- package/lib/parser/index.d.ts +5 -0
- package/lib/parser/index.d.ts.map +1 -0
- package/lib/parser/index.js +4 -0
- package/lib/parser/index.js.map +1 -0
- package/lib/parser/interfaces.d.ts +46 -0
- package/lib/parser/interfaces.d.ts.map +1 -0
- package/lib/parser/interfaces.js +2 -0
- package/lib/parser/interfaces.js.map +1 -0
- package/lib/parser/position-utils.d.ts +39 -0
- package/lib/parser/position-utils.d.ts.map +1 -0
- package/lib/parser/position-utils.js +102 -0
- package/lib/parser/position-utils.js.map +1 -0
- package/lib/parser/record-parser.d.ts +29 -0
- package/lib/parser/record-parser.d.ts.map +1 -0
- package/lib/parser/record-parser.js +104 -0
- package/lib/parser/record-parser.js.map +1 -0
- package/lib/parser/table-parsers.d.ts +27 -0
- package/lib/parser/table-parsers.d.ts.map +1 -0
- package/lib/parser/table-parsers.js +178 -0
- package/lib/parser/table-parsers.js.map +1 -0
- package/lib/record.d.ts +55 -0
- package/lib/record.d.ts.map +1 -0
- package/lib/record.js +5 -0
- package/lib/record.js.map +1 -0
- package/lib/serializer/index.d.ts +3 -0
- package/lib/serializer/index.d.ts.map +1 -0
- package/lib/serializer/index.js +2 -0
- package/lib/serializer/index.js.map +1 -0
- package/lib/serializer/interfaces.d.ts +14 -0
- package/lib/serializer/interfaces.d.ts.map +1 -0
- package/lib/serializer/interfaces.js +2 -0
- package/lib/serializer/interfaces.js.map +1 -0
- package/lib/serializer/record-serializer.d.ts +24 -0
- package/lib/serializer/record-serializer.d.ts.map +1 -0
- package/lib/serializer/record-serializer.js +176 -0
- package/lib/serializer/record-serializer.js.map +1 -0
- package/lib/splash/index.d.ts +3 -0
- package/lib/splash/index.d.ts.map +1 -0
- package/lib/splash/index.js +2 -0
- package/lib/splash/index.js.map +1 -0
- package/lib/splash/interfaces.d.ts +22 -0
- package/lib/splash/interfaces.d.ts.map +1 -0
- package/lib/splash/interfaces.js +2 -0
- package/lib/splash/interfaces.js.map +1 -0
- package/lib/splash/splash-validator.d.ts +31 -0
- package/lib/splash/splash-validator.d.ts.map +1 -0
- package/lib/splash/splash-validator.js +79 -0
- package/lib/splash/splash-validator.js.map +1 -0
- package/lib/types.d.ts +92 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/validation/index.d.ts +4 -0
- package/lib/validation/index.d.ts.map +1 -0
- package/lib/validation/index.js +3 -0
- package/lib/validation/index.js.map +1 -0
- package/lib/validation/interfaces.d.ts +24 -0
- package/lib/validation/interfaces.d.ts.map +1 -0
- package/lib/validation/interfaces.js +2 -0
- package/lib/validation/interfaces.js.map +1 -0
- package/lib/validation/rules/accession-match-rule.d.ts +13 -0
- package/lib/validation/rules/accession-match-rule.d.ts.map +1 -0
- package/lib/validation/rules/accession-match-rule.js +40 -0
- package/lib/validation/rules/accession-match-rule.js.map +1 -0
- package/lib/validation/rules/index.d.ts +5 -0
- package/lib/validation/rules/index.d.ts.map +1 -0
- package/lib/validation/rules/index.js +5 -0
- package/lib/validation/rules/index.js.map +1 -0
- package/lib/validation/rules/non-standard-chars-rule.d.ts +13 -0
- package/lib/validation/rules/non-standard-chars-rule.d.ts.map +1 -0
- package/lib/validation/rules/non-standard-chars-rule.js +61 -0
- package/lib/validation/rules/non-standard-chars-rule.js.map +1 -0
- package/lib/validation/rules/serialization-rule.d.ts +14 -0
- package/lib/validation/rules/serialization-rule.d.ts.map +1 -0
- package/lib/validation/rules/serialization-rule.js +78 -0
- package/lib/validation/rules/serialization-rule.js.map +1 -0
- package/lib/validation/rules/unrecognized-field-rule.d.ts +25 -0
- package/lib/validation/rules/unrecognized-field-rule.d.ts.map +1 -0
- package/lib/validation/rules/unrecognized-field-rule.js +149 -0
- package/lib/validation/rules/unrecognized-field-rule.js.map +1 -0
- package/lib/validation/validator.d.ts +18 -0
- package/lib/validation/validator.d.ts.map +1 -0
- package/lib/validation/validator.js +30 -0
- package/lib/validation/validator.js.map +1 -0
- package/lib/validator/file-utils.d.ts +13 -0
- package/lib/validator/file-utils.d.ts.map +1 -0
- package/lib/validator/file-utils.js +24 -0
- package/lib/validator/file-utils.js.map +1 -0
- package/lib/validator/index.d.ts +2 -0
- package/lib/validator/index.d.ts.map +1 -0
- package/lib/validator/index.js +2 -0
- package/lib/validator/index.js.map +1 -0
- package/lib/validator/validator.d.ts +19 -0
- package/lib/validator/validator.d.ts.map +1 -0
- package/lib/validator/validator.js +159 -0
- package/lib/validator/validator.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +13 -5
- package/src/parser/exceptions.ts +24 -0
- package/src/parser/field-parsers.ts +237 -0
- package/src/parser/index.ts +8 -0
- package/src/parser/interfaces.ts +56 -0
- package/src/parser/position-utils.ts +130 -0
- package/src/parser/record-parser.ts +155 -0
- package/src/parser/table-parsers.ts +217 -0
- package/src/record.ts +71 -0
- package/src/serializer/index.ts +6 -0
- package/src/serializer/interfaces.ts +14 -0
- package/src/serializer/record-serializer.ts +192 -0
- package/src/splash/index.ts +2 -0
- package/src/splash/interfaces.ts +20 -0
- package/src/splash/splash-validator.ts +95 -0
- package/src/types.ts +96 -0
- package/src/validation/index.ts +3 -0
- package/src/validation/interfaces.ts +36 -0
- package/src/validation/rules/accession-match-rule.ts +55 -0
- package/src/validation/rules/index.ts +4 -0
- package/src/validation/rules/non-standard-chars-rule.ts +86 -0
- package/src/validation/rules/serialization-rule.ts +101 -0
- package/src/validation/rules/unrecognized-field-rule.ts +172 -0
- package/src/validation/validator.ts +39 -0
- package/src/validator/file-utils.ts +25 -0
- package/src/validator/index.ts +1 -0
- package/src/validator/validator.ts +189 -0
- package/lib/isValid.d.ts +0 -12
- package/lib/isValid.d.ts.map +0 -1
- package/lib/isValid.js +0 -15
- package/lib/isValid.js.map +0 -1
- package/src/isValid.ts +0 -22
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { PositionUtils } from '../../parser/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Pattern for allowed characters (from Java Validator).
|
|
4
|
+
* Note: We deliberately allow both LF (`\n`) and CR (`\r`) here so CRLF
|
|
5
|
+
* line endings do not trigger non-standard character warnings. The Java CLI
|
|
6
|
+
* treats CR as non-standard only via logging; for this library we avoid
|
|
7
|
+
* warning on platform-specific line endings while still flagging real
|
|
8
|
+
* non-ASCII issues.
|
|
9
|
+
*/
|
|
10
|
+
const NON_STANDARD_CHARS_PATTERN = /[^\w\r\n\-[\]."\\ ;:–=+,|(){}/$%@'°!?#`^*&<>µáćÉéóäöü©]/;
|
|
11
|
+
/**
|
|
12
|
+
* Validates non-standard characters in the record
|
|
13
|
+
* Only validates character set.
|
|
14
|
+
* This rule is warning-only and never produces blocking validation errors.
|
|
15
|
+
*/
|
|
16
|
+
export class NonStandardCharsRule {
|
|
17
|
+
validate(_record, _originalText, _filename, _options) {
|
|
18
|
+
void _record;
|
|
19
|
+
void _originalText;
|
|
20
|
+
void _filename;
|
|
21
|
+
void _options;
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
getWarnings(record, originalText, filename,
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
26
|
+
_options) {
|
|
27
|
+
const warnings = [];
|
|
28
|
+
// Skip deprecated records
|
|
29
|
+
if (record.DEPRECATED) {
|
|
30
|
+
return warnings;
|
|
31
|
+
}
|
|
32
|
+
const match = NON_STANDARD_CHARS_PATTERN.exec(originalText);
|
|
33
|
+
if (match?.index !== undefined) {
|
|
34
|
+
const { line, column } = PositionUtils.getLineColumn(originalText, match.index);
|
|
35
|
+
const char = match[0] || '';
|
|
36
|
+
const codePoint = char.codePointAt(0);
|
|
37
|
+
const hex = codePoint
|
|
38
|
+
? `U+${codePoint.toString(16).toUpperCase().padStart(4, '0')}`
|
|
39
|
+
: '';
|
|
40
|
+
// Common replacements
|
|
41
|
+
const suggestions = new Map([
|
|
42
|
+
['\u2014', 'Replace em-dash with hyphen'],
|
|
43
|
+
['\u201C', 'Replace fancy opening quote with straight quote (")'],
|
|
44
|
+
['\u201D', 'Replace fancy closing quote with straight quote (")'],
|
|
45
|
+
['\u2018', "Replace fancy opening apostrophe with straight quote (')"],
|
|
46
|
+
['\u2019', "Replace fancy closing apostrophe with straight quote (')"],
|
|
47
|
+
['\u2022', 'Replace bullet point with hyphen (-)'],
|
|
48
|
+
['\u00AE', 'Replace registered symbol with (R)'],
|
|
49
|
+
]);
|
|
50
|
+
const suggestion = suggestions.get(char) || 'Replace with standard ASCII character';
|
|
51
|
+
warnings.push({
|
|
52
|
+
file: filename,
|
|
53
|
+
line,
|
|
54
|
+
column,
|
|
55
|
+
message: `Non-standard character '${char}' (${hex}) found. ${suggestion}`,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return warnings;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=non-standard-chars-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"non-standard-chars-rule.js","sourceRoot":"","sources":["../../../src/validation/rules/non-standard-chars-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAKtD;;;;;;;GAOG;AACH,MAAM,0BAA0B,GAC9B,yDAAyD,CAAC;AAE5D;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IAC/B,QAAQ,CACN,OAAe,EACf,aAAqB,EACrB,SAAiB,EACjB,QAA+B;QAE/B,KAAK,OAAO,CAAC;QACb,KAAK,aAAa,CAAC;QACnB,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ,CAAC;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,WAAW,CACT,MAAc,EACd,YAAoB,EACpB,QAAgB;IAChB,6DAA6D;IAC7D,QAA+B;QAE/B,MAAM,QAAQ,GAAwB,EAAE,CAAC;QAEzC,0BAA0B;QAC1B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,0BAA0B,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5D,IAAI,KAAK,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,aAAa,CAClD,YAAY,EACZ,KAAK,CAAC,KAAK,CACZ,CAAC;YACF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,SAAS;gBACnB,CAAC,CAAC,KAAK,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;gBAC9D,CAAC,CAAC,EAAE,CAAC;YAEP,sBAAsB;YACtB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAiB;gBAC1C,CAAC,QAAQ,EAAE,6BAA6B,CAAC;gBACzC,CAAC,QAAQ,EAAE,qDAAqD,CAAC;gBACjE,CAAC,QAAQ,EAAE,qDAAqD,CAAC;gBACjE,CAAC,QAAQ,EAAE,0DAA0D,CAAC;gBACtE,CAAC,QAAQ,EAAE,0DAA0D,CAAC;gBACtE,CAAC,QAAQ,EAAE,sCAAsC,CAAC;gBAClD,CAAC,QAAQ,EAAE,oCAAoC,CAAC;aACjD,CAAC,CAAC;YAEH,MAAM,UAAU,GACd,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,uCAAuC,CAAC;YAEnE,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,QAAQ;gBACd,IAAI;gBACJ,MAAM;gBACN,OAAO,EAAE,2BAA2B,IAAI,MAAM,GAAG,YAAY,UAAU,EAAE;aAC1E,CAAC,CAAC;QACL,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Record } from '../../record.js';
|
|
2
|
+
import type { ValidationError, ValidationWarning } from '../../types.js';
|
|
3
|
+
import type { IValidationRule, ValidationRuleOptions } from '../interfaces.js';
|
|
4
|
+
/**
|
|
5
|
+
* Validates serialization round-trip (parse -> serialize -> compare)
|
|
6
|
+
* Only validates serialization consistency.
|
|
7
|
+
* This rule produces blocking validation errors but no warnings.
|
|
8
|
+
*/
|
|
9
|
+
export declare class SerializationRule implements IValidationRule {
|
|
10
|
+
validate(record: Record, originalText: string, filename: string, _options: ValidationRuleOptions): ValidationError[];
|
|
11
|
+
getWarnings(): ValidationWarning[];
|
|
12
|
+
private findFirstDifference;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=serialization-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization-rule.d.ts","sourceRoot":"","sources":["../../../src/validation/rules/serialization-rule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE/E;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IACvD,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAEhB,QAAQ,EAAE,qBAAqB,GAC9B,eAAe,EAAE;IAkEpB,WAAW,IAAI,iBAAiB,EAAE;IAIlC,OAAO,CAAC,mBAAmB;CAY5B"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { PositionUtils } from '../../parser/index.js';
|
|
2
|
+
import { serializeRecord } from '../../serializer/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Validates serialization round-trip (parse -> serialize -> compare)
|
|
5
|
+
* Only validates serialization consistency.
|
|
6
|
+
* This rule produces blocking validation errors but no warnings.
|
|
7
|
+
*/
|
|
8
|
+
export class SerializationRule {
|
|
9
|
+
validate(record, originalText, filename,
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
11
|
+
_options) {
|
|
12
|
+
const errors = [];
|
|
13
|
+
try {
|
|
14
|
+
const serialized = serializeRecord(record);
|
|
15
|
+
// eslint-disable-next-line unicorn/prefer-string-replace-all
|
|
16
|
+
const normalizedOriginal = originalText.replace(/\r\n?/g, '\n');
|
|
17
|
+
// Find first difference
|
|
18
|
+
const diffPosition = this.findFirstDifference(normalizedOriginal, serialized);
|
|
19
|
+
if (diffPosition !== -1) {
|
|
20
|
+
const { line, column } = PositionUtils.getLineColumn(normalizedOriginal, diffPosition);
|
|
21
|
+
// Get context around the difference for better error message
|
|
22
|
+
const originalLine = normalizedOriginal.split('\n')[line - 1] || '';
|
|
23
|
+
const serializedLine = serialized.split('\n')[line - 1] || '';
|
|
24
|
+
let message = 'File formatting issue detected (round-trip validation failed).';
|
|
25
|
+
// Provide specific guidance based on common issues
|
|
26
|
+
if (originalLine !== serializedLine) {
|
|
27
|
+
if (originalLine.includes(' ') && serializedLine.includes(' ')) {
|
|
28
|
+
message += ' Check for extra spaces or inconsistent spacing.';
|
|
29
|
+
}
|
|
30
|
+
else if (!serializedLine.trim()) {
|
|
31
|
+
message +=
|
|
32
|
+
' This line may contain unrecognized fields that were ignored during parsing.';
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const expectedPreview = serializedLine.length > 80
|
|
36
|
+
? `${serializedLine.slice(0, 77)}...`
|
|
37
|
+
: serializedLine;
|
|
38
|
+
const foundPreview = originalLine.length > 80
|
|
39
|
+
? `${originalLine.slice(0, 77)}...`
|
|
40
|
+
: originalLine;
|
|
41
|
+
message += ` Expected (${serializedLine.length} chars): "${expectedPreview}" but found (${originalLine.length} chars): "${foundPreview}"`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
errors.push({
|
|
45
|
+
file: filename,
|
|
46
|
+
line,
|
|
47
|
+
column,
|
|
48
|
+
message,
|
|
49
|
+
type: 'serialization',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
errors.push({
|
|
55
|
+
file: filename,
|
|
56
|
+
message: `Serialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
57
|
+
type: 'serialization',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return errors;
|
|
61
|
+
}
|
|
62
|
+
getWarnings() {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
findFirstDifference(str1, str2) {
|
|
66
|
+
const minLength = Math.min(str1.length, str2.length);
|
|
67
|
+
for (let i = 0; i < minLength; i++) {
|
|
68
|
+
if (str1[i] !== str2[i]) {
|
|
69
|
+
return i;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (str1.length !== str2.length) {
|
|
73
|
+
return minLength;
|
|
74
|
+
}
|
|
75
|
+
return -1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=serialization-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization-rule.js","sourceRoot":"","sources":["../../../src/validation/rules/serialization-rule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Record } from '../../record.js';
|
|
2
|
+
import type { ValidationWarning } from '../../types.js';
|
|
3
|
+
import type { IValidationRule, ValidationRuleOptions } from '../interfaces.js';
|
|
4
|
+
/**
|
|
5
|
+
* Validation rule that warns about unrecognized fields
|
|
6
|
+
* Helps catch typos and unsupported field names
|
|
7
|
+
*/
|
|
8
|
+
export declare class UnrecognizedFieldRule implements IValidationRule {
|
|
9
|
+
/**
|
|
10
|
+
* List of all recognized MassBank 2.6.0 field names
|
|
11
|
+
*/
|
|
12
|
+
private readonly recognizedFields;
|
|
13
|
+
validate(_record: Record, _originalText: string, _filename: string, _options?: ValidationRuleOptions): never[];
|
|
14
|
+
getWarnings(_record: Record, originalText: string, filename: string, _options?: ValidationRuleOptions): ValidationWarning[];
|
|
15
|
+
/**
|
|
16
|
+
* Find a similar field name for typo suggestions
|
|
17
|
+
* Uses simple Levenshtein distance for similarity
|
|
18
|
+
*/
|
|
19
|
+
private findSimilarField;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate Levenshtein distance between two strings
|
|
22
|
+
*/
|
|
23
|
+
private levenshteinDistance;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=unrecognized-field-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unrecognized-field-rule.d.ts","sourceRoot":"","sources":["../../../src/validation/rules/unrecognized-field-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE/E;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IAC3D;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAsC9B;IAEH,QAAQ,CAEN,OAAO,EAAE,MAAM,EAEf,aAAa,EAAE,MAAM,EAErB,SAAS,EAAE,MAAM,EAEjB,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,KAAK,EAAE;IAKV,WAAW,CACT,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAEhB,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,iBAAiB,EAAE;IA0CtB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAkC5B"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation rule that warns about unrecognized fields
|
|
3
|
+
* Helps catch typos and unsupported field names
|
|
4
|
+
*/
|
|
5
|
+
export class UnrecognizedFieldRule {
|
|
6
|
+
/**
|
|
7
|
+
* List of all recognized MassBank 2.6.0 field names
|
|
8
|
+
*/
|
|
9
|
+
recognizedFields = new Set([
|
|
10
|
+
// Header fields
|
|
11
|
+
'ACCESSION',
|
|
12
|
+
'RECORD_TITLE',
|
|
13
|
+
'DATE',
|
|
14
|
+
'AUTHORS',
|
|
15
|
+
'LICENSE',
|
|
16
|
+
'COPYRIGHT',
|
|
17
|
+
'PUBLICATION',
|
|
18
|
+
'PROJECT',
|
|
19
|
+
'COMMENT',
|
|
20
|
+
'DEPRECATED',
|
|
21
|
+
// Chemical compound fields
|
|
22
|
+
'CH$NAME',
|
|
23
|
+
'CH$COMPOUND_CLASS',
|
|
24
|
+
'CH$FORMULA',
|
|
25
|
+
'CH$EXACT_MASS',
|
|
26
|
+
'CH$SMILES',
|
|
27
|
+
'CH$IUPAC',
|
|
28
|
+
'CH$LINK',
|
|
29
|
+
// Analytical chemistry fields
|
|
30
|
+
'AC$INSTRUMENT',
|
|
31
|
+
'AC$INSTRUMENT_TYPE',
|
|
32
|
+
'AC$MASS_SPECTROMETRY',
|
|
33
|
+
'AC$CHROMATOGRAPHY',
|
|
34
|
+
// Mass spectrometry fields
|
|
35
|
+
'MS$FOCUSED_ION',
|
|
36
|
+
'MS$DATA_PROCESSING',
|
|
37
|
+
// Peak data fields
|
|
38
|
+
'PK$SPLASH',
|
|
39
|
+
'PK$NUM_PEAK',
|
|
40
|
+
'PK$PEAK',
|
|
41
|
+
'PK$ANNOTATION',
|
|
42
|
+
// Sample/species fields
|
|
43
|
+
'SP$SCIENTIFIC_NAME',
|
|
44
|
+
'SP$LINEAGE',
|
|
45
|
+
'SP$LINK',
|
|
46
|
+
'SP$SAMPLE',
|
|
47
|
+
]);
|
|
48
|
+
validate(
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
50
|
+
_record,
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
52
|
+
_originalText,
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
54
|
+
_filename,
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
56
|
+
_options) {
|
|
57
|
+
// This rule only produces warnings, not errors
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
getWarnings(_record, originalText, filename,
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
62
|
+
_options) {
|
|
63
|
+
const warnings = [];
|
|
64
|
+
const lines = originalText.split('\n');
|
|
65
|
+
for (let i = 0; i < lines.length; i++) {
|
|
66
|
+
const line = lines[i]?.trim();
|
|
67
|
+
if (!line || line === '//' || line.startsWith('//')) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const colonIndex = line.indexOf(':');
|
|
71
|
+
if (colonIndex === -1) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const key = line.slice(0, colonIndex).trim();
|
|
75
|
+
// Check if this is an unrecognized field
|
|
76
|
+
if (!this.recognizedFields.has(key)) {
|
|
77
|
+
// Suggest similar field names for common typos
|
|
78
|
+
// Normalize to uppercase for comparison to catch case errors
|
|
79
|
+
const suggestion = this.findSimilarField(key.toUpperCase());
|
|
80
|
+
let message = `Unrecognized field '${key}'. Not a valid MassBank 2.6.0 field.`;
|
|
81
|
+
if (suggestion) {
|
|
82
|
+
message += ` Did you mean '${suggestion}'?`;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
message +=
|
|
86
|
+
' Remove this line or check the MassBank format specification.';
|
|
87
|
+
}
|
|
88
|
+
warnings.push({
|
|
89
|
+
file: filename,
|
|
90
|
+
line: i + 1,
|
|
91
|
+
message,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return warnings;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Find a similar field name for typo suggestions
|
|
99
|
+
* Uses simple Levenshtein distance for similarity
|
|
100
|
+
*/
|
|
101
|
+
findSimilarField(input) {
|
|
102
|
+
let bestMatch = null;
|
|
103
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
104
|
+
for (const field of this.recognizedFields) {
|
|
105
|
+
const distance = this.levenshteinDistance(input, field);
|
|
106
|
+
// Only suggest if very similar (distance <= 2)
|
|
107
|
+
if (distance <= 2 && distance < bestDistance) {
|
|
108
|
+
bestDistance = distance;
|
|
109
|
+
bestMatch = field;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return bestMatch;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Calculate Levenshtein distance between two strings
|
|
116
|
+
*/
|
|
117
|
+
levenshteinDistance(a, b) {
|
|
118
|
+
const matrix = [];
|
|
119
|
+
for (let i = 0; i <= b.length; i++) {
|
|
120
|
+
matrix[i] = [i];
|
|
121
|
+
}
|
|
122
|
+
const firstRow = matrix[0];
|
|
123
|
+
if (firstRow) {
|
|
124
|
+
for (let j = 0; j <= a.length; j++) {
|
|
125
|
+
firstRow[j] = j;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (let i = 1; i <= b.length; i++) {
|
|
129
|
+
const currentRow = matrix[i];
|
|
130
|
+
const prevRow = matrix[i - 1];
|
|
131
|
+
if (!currentRow || !prevRow)
|
|
132
|
+
continue;
|
|
133
|
+
for (let j = 1; j <= a.length; j++) {
|
|
134
|
+
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
135
|
+
currentRow[j] = prevRow[j - 1] ?? 0;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const substitution = (prevRow[j - 1] ?? 0) + 1;
|
|
139
|
+
const insertion = (currentRow[j - 1] ?? 0) + 1;
|
|
140
|
+
const deletion = (prevRow[j] ?? 0) + 1;
|
|
141
|
+
currentRow[j] = Math.min(substitution, insertion, deletion);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const lastRow = matrix[b.length];
|
|
146
|
+
return lastRow?.[a.length] ?? Number.POSITIVE_INFINITY;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=unrecognized-field-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unrecognized-field-rule.js","sourceRoot":"","sources":["../../../src/validation/rules/unrecognized-field-rule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IValidationRule } from './interfaces.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validator that applies all validation rules to a record
|
|
4
|
+
*/
|
|
5
|
+
export declare class RecordValidator {
|
|
6
|
+
private readonly rules;
|
|
7
|
+
constructor(rules?: IValidationRule[]);
|
|
8
|
+
/**
|
|
9
|
+
* Add a validation rule
|
|
10
|
+
* @param rule
|
|
11
|
+
*/
|
|
12
|
+
addRule(rule: IValidationRule): void;
|
|
13
|
+
/**
|
|
14
|
+
* Get all validation rules
|
|
15
|
+
*/
|
|
16
|
+
getRules(): readonly IValidationRule[];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/validation/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAQvD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;gBAE9B,KAAK,CAAC,EAAE,eAAe,EAAE;IAUrC;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAIpC;;OAEG;IACH,QAAQ,IAAI,SAAS,eAAe,EAAE;CAGvC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AccessionMatchRule, NonStandardCharsRule, SerializationRule, UnrecognizedFieldRule, } from './rules/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validator that applies all validation rules to a record
|
|
4
|
+
*/
|
|
5
|
+
export class RecordValidator {
|
|
6
|
+
rules;
|
|
7
|
+
constructor(rules) {
|
|
8
|
+
// Default rules (can be overridden via dependency injection)
|
|
9
|
+
this.rules = rules || [
|
|
10
|
+
new AccessionMatchRule(),
|
|
11
|
+
new NonStandardCharsRule(),
|
|
12
|
+
new SerializationRule(),
|
|
13
|
+
new UnrecognizedFieldRule(),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Add a validation rule
|
|
18
|
+
* @param rule
|
|
19
|
+
*/
|
|
20
|
+
addRule(rule) {
|
|
21
|
+
this.rules.push(rule);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get all validation rules
|
|
25
|
+
*/
|
|
26
|
+
getRules() {
|
|
27
|
+
return this.rules;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/validation/validator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B;;GAEG;AACH,MAAM,OAAO,eAAe;IACT,KAAK,CAAoB;IAE1C,YAAY,KAAyB;QACnC,6DAA6D;QAC7D,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI;YACpB,IAAI,kBAAkB,EAAE;YACxB,IAAI,oBAAoB,EAAE;YAC1B,IAAI,iBAAiB,EAAE;YACvB,IAAI,qBAAqB,EAAE;SAC5B,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,IAAqB;QAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for file operations
|
|
3
|
+
* Simplified for single-file validation
|
|
4
|
+
*/
|
|
5
|
+
export declare const FileUtils: {
|
|
6
|
+
/**
|
|
7
|
+
* Read a file as UTF-8 text
|
|
8
|
+
* @param filePath - Absolute path to the file
|
|
9
|
+
* @returns File content as string
|
|
10
|
+
*/
|
|
11
|
+
readFile(filePath: string): Promise<string>;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=file-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/validator/file-utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,SAAS;IACpB;;;;OAIG;uBACsB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAYlD,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
/**
|
|
3
|
+
* Utility functions for file operations
|
|
4
|
+
* Simplified for single-file validation
|
|
5
|
+
*/
|
|
6
|
+
export const FileUtils = {
|
|
7
|
+
/**
|
|
8
|
+
* Read a file as UTF-8 text
|
|
9
|
+
* @param filePath - Absolute path to the file
|
|
10
|
+
* @returns File content as string
|
|
11
|
+
*/
|
|
12
|
+
async readFile(filePath) {
|
|
13
|
+
try {
|
|
14
|
+
return await readFile(filePath, 'utf8');
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
18
|
+
const wrappedError = new Error(`Error reading file ${filePath}: ${message}`);
|
|
19
|
+
wrappedError.cause = error;
|
|
20
|
+
throw wrappedError;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=file-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-utils.js","sourceRoot":"","sources":["../../src/validator/file-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,QAAgB;QAC7B,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACzE,MAAM,YAAY,GAAG,IAAI,KAAK,CAC5B,sBAAsB,QAAQ,KAAK,OAAO,EAAE,CAC7C,CAAC;YACD,YAAoC,CAAC,KAAK,GAAG,KAAK,CAAC;YACpD,MAAM,YAAY,CAAC;QACrB,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ValidationOptions, ValidationResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validate a single MassBank record file
|
|
4
|
+
* @param filePath - Path to the .txt file
|
|
5
|
+
* @param options - Validation options (legacy mode, logger)
|
|
6
|
+
* @returns ValidationResult with errors, warnings, and accession
|
|
7
|
+
*/
|
|
8
|
+
export declare function validate(filePath: string, options?: ValidationOptions): Promise<ValidationResult>;
|
|
9
|
+
/**
|
|
10
|
+
* Validate in-memory MassBank record content
|
|
11
|
+
* Useful for browser or API use-cases where the record content is not
|
|
12
|
+
* coming from the filesystem.
|
|
13
|
+
* @param content - Full record text to validate
|
|
14
|
+
* @param filename - Logical filename for error reporting (e.g. 'user-upload.txt')
|
|
15
|
+
* @param options - Validation options (legacy mode, logger)
|
|
16
|
+
* @returns ValidationResult with errors, warnings, and accession
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateContent(content: string, filename: string, options?: ValidationOptions): Promise<ValidationResult>;
|
|
19
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/validator/validator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAGrB;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAiG3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CA0D3B"}
|