@prefixcheck/edi 0.1.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/LICENSE +21 -0
- package/README.md +201 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +30 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +247 -0
- package/dist/parser.js.map +1 -0
- package/dist/samples.d.ts +15 -0
- package/dist/samples.d.ts.map +1 -0
- package/dist/samples.js +100 -0
- package/dist/samples.js.map +1 -0
- package/dist/schemas.d.ts +79 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +951 -0
- package/dist/schemas.js.map +1 -0
- package/dist/types.d.ts +104 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +83 -0
package/dist/samples.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @prefixcheck/edi · sample messages for demos, tests, and docs
|
|
3
|
+
//
|
|
4
|
+
// Real-shape SMDG D.00B CODECO + COPRAR messages with valid
|
|
5
|
+
// ISO 6346 container check digits. The container number
|
|
6
|
+
// MSCU1234566 appears in both so that `reconcile()` against
|
|
7
|
+
// them produces a clean cross-match in tests and examples.
|
|
8
|
+
// ============================================================
|
|
9
|
+
/**
|
|
10
|
+
* A complete SMDG-shape CODECO message: gate-in report from
|
|
11
|
+
* terminal ECT Rotterdam to carrier MSC, one full 40-foot
|
|
12
|
+
* high-cube container (MSCU1234566) bound for New York.
|
|
13
|
+
*/
|
|
14
|
+
export const SAMPLE_CODECO = `UNA:+.? '
|
|
15
|
+
UNB+UNOA:2+TERMINAL01:ZZZ+MSCU:ZZZ+260524:1430+CDC00012345'
|
|
16
|
+
UNH+CDC0001+CODECO:D:00B:UN:SMDG21'
|
|
17
|
+
BGM+34:::TRANSPORT EQUIPMENT GATE IN REPORT+CDC0001+9'
|
|
18
|
+
DTM+137:202605241430:203'
|
|
19
|
+
TDT+20+251NB+3+31+MSCU:172:20'
|
|
20
|
+
LOC+9+NLRTM:139:6+ECT:TER:ZZZ'
|
|
21
|
+
DTM+178:202605241425:203'
|
|
22
|
+
NAD+CF+MSC:160:20'
|
|
23
|
+
NAD+TR+ECT:160:20'
|
|
24
|
+
NAD+CA+MSCU:172:20'
|
|
25
|
+
EQD+CN+MSCU1234566+45G1:102:5++2+4'
|
|
26
|
+
RFF+BN:BKG778899'
|
|
27
|
+
RFF+BM:MSCUNLRTM0042'
|
|
28
|
+
RFF+EQ:MSCU1234566'
|
|
29
|
+
DTM+178:202605241425:203'
|
|
30
|
+
LOC+9+NLRTM:139:6+ECT:TER:ZZZ'
|
|
31
|
+
LOC+11+USNYC:139:6'
|
|
32
|
+
LOC+165+USNYC:139:6'
|
|
33
|
+
MEA+AAE+AET+KGM:28450'
|
|
34
|
+
MEA+AAL++KGM:3920'
|
|
35
|
+
MEA+VGM++KGM:28450'
|
|
36
|
+
SEL+CN789456+CA'
|
|
37
|
+
SEL+TR556677+TR'
|
|
38
|
+
FTX+AAA+++FULL CONTAINER GATE IN'
|
|
39
|
+
EQA+CH+CHSU0099887'
|
|
40
|
+
STS+1+2'
|
|
41
|
+
DTM+178:202605241430:203'
|
|
42
|
+
CNT+16:1'
|
|
43
|
+
UNT+28+CDC0001'
|
|
44
|
+
UNZ+1+CDC00012345'`;
|
|
45
|
+
/**
|
|
46
|
+
* A complete SMDG-shape COPRAR Load order: carrier MSC instructs
|
|
47
|
+
* terminal ECT Rotterdam to load three containers on vessel
|
|
48
|
+
* MSC MAYA (voyage 251NB) bound for New York. The first container
|
|
49
|
+
* (MSCU1234566) matches the CODECO sample above so the pair
|
|
50
|
+
* cross-reconciles cleanly. Container 3 is a frozen reefer.
|
|
51
|
+
*/
|
|
52
|
+
export const SAMPLE_COPRAR = `UNA:+.? '
|
|
53
|
+
UNB+UNOA:2+MSCU:ZZZ+TERMINAL01:ZZZ+260524:1200+CPR00098765'
|
|
54
|
+
UNH+CPR0001+COPRAR:D:00B:UN:SMDG21'
|
|
55
|
+
BGM+45+CPR0001+9'
|
|
56
|
+
DTM+137:202605241200:203'
|
|
57
|
+
RFF+XXX:VOY-251NB-LOAD'
|
|
58
|
+
TDT+20+251NB+1+13+MSCU:172:20+++9876543:146:11::MSC MAYA'
|
|
59
|
+
LOC+9+NLRTM:139:6+ECT:TER:ZZZ'
|
|
60
|
+
DTM+133:202605260800:203'
|
|
61
|
+
LOC+11+USNYC:139:6'
|
|
62
|
+
DTM+132:202606051400:203'
|
|
63
|
+
NAD+CA+MSCU:172:20'
|
|
64
|
+
NAD+CF+MSC:160:20'
|
|
65
|
+
NAD+TR+ECT:160:20'
|
|
66
|
+
EQD+CN+MSCU1234566+45G1:102:5++4+4'
|
|
67
|
+
RFF+BN:BKG778899'
|
|
68
|
+
RFF+BM:MSCUNLRTM0042'
|
|
69
|
+
LOC+9+NLRTM:139:6'
|
|
70
|
+
LOC+11+USNYC:139:6'
|
|
71
|
+
MEA+AAE++KGM:28450'
|
|
72
|
+
MEA+AAL++KGM:3920'
|
|
73
|
+
MEA+VGM++KGM:28450'
|
|
74
|
+
TPL+++147:021082'
|
|
75
|
+
EQD+CN+MSCU2345672+22G1:102:5++4+4'
|
|
76
|
+
RFF+BN:BKG778900'
|
|
77
|
+
RFF+BM:MSCUNLRTM0043'
|
|
78
|
+
LOC+9+NLRTM:139:6'
|
|
79
|
+
LOC+11+USNYC:139:6'
|
|
80
|
+
MEA+AAE++KGM:18200'
|
|
81
|
+
MEA+AAL++KGM:2230'
|
|
82
|
+
MEA+VGM++KGM:18200'
|
|
83
|
+
TPL+++147:019084'
|
|
84
|
+
EQD+CN+MSCU3456789+45R1:102:5++4+4'
|
|
85
|
+
RFF+BN:BKG778901'
|
|
86
|
+
RFF+BM:MSCUNLRTM0044'
|
|
87
|
+
LOC+9+NLRTM:139:6'
|
|
88
|
+
LOC+11+USNYC:139:6'
|
|
89
|
+
TMP+2+-018:CEL'
|
|
90
|
+
RNG+5+CEL:-020:-015'
|
|
91
|
+
MEA+AAE++KGM:27800'
|
|
92
|
+
MEA+AAL++KGM:4500'
|
|
93
|
+
MEA+VGM++KGM:27800'
|
|
94
|
+
EQA+RG+MSCG0001122'
|
|
95
|
+
TPL+++147:023086'
|
|
96
|
+
CNT+16:3'
|
|
97
|
+
CNT+7:5'
|
|
98
|
+
UNT+46+CPR0001'
|
|
99
|
+
UNZ+1+CPR00098765'`;
|
|
100
|
+
//# sourceMappingURL=samples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"samples.js","sourceRoot":"","sources":["../src/samples.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,gEAAgE;AAChE,EAAE;AACF,4DAA4D;AAC5D,wDAAwD;AACxD,4DAA4D;AAC5D,2DAA2D;AAC3D,+DAA+D;AAE/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA8BV,CAAC;AAEpB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA+CV,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Diagnostic, MessageSchema, MessageType, ParsedMessage, ReconcileReport } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validate an ISO 6346 container number's check digit (11th character).
|
|
4
|
+
* Letter values skip every multiple of 11.
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateCheckDigit(code: string): boolean;
|
|
7
|
+
export interface SegmentInfo {
|
|
8
|
+
name: string;
|
|
9
|
+
brief: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const SEGMENTS: Record<string, SegmentInfo>;
|
|
12
|
+
type CodeList = Record<string, string>;
|
|
13
|
+
export declare const CODE_LISTS: Record<string, CodeList>;
|
|
14
|
+
/**
|
|
15
|
+
* Decode a 4-character ISO 6346 size-type code into operator-readable
|
|
16
|
+
* parts: size, type group, height/variant, variant digit.
|
|
17
|
+
*
|
|
18
|
+
* Returns `null` if the input doesn't look like a valid size-type code.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* decodeISOSizeType("45R1"); // "40ft · Integral reefer · 9ft 6in (high cube) · variant 1"
|
|
23
|
+
* decodeISOSizeType("22G1"); // "20ft · General purpose · 8ft 6in (standard) · variant 1"
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function decodeISOSizeType(code: string): string | null;
|
|
27
|
+
export declare const CODECO: MessageSchema;
|
|
28
|
+
export declare const COPRAR: MessageSchema;
|
|
29
|
+
/**
|
|
30
|
+
* Detect whether the parsed message is CODECO, COPRAR, or unknown.
|
|
31
|
+
* Inspects UNH.type first, then falls back to BGM document code.
|
|
32
|
+
*/
|
|
33
|
+
export declare function detectMessageType(parsed: ParsedMessage): MessageType;
|
|
34
|
+
/** Look up a code in a named list. Returns null if the list or code is unknown. */
|
|
35
|
+
export declare function lookup(listName: string, code: string): string | null;
|
|
36
|
+
/** Get the segment dictionary entry for a 3-letter tag. */
|
|
37
|
+
export declare function segmentInfo(tag: string): SegmentInfo;
|
|
38
|
+
/**
|
|
39
|
+
* Run all single-message diagnostic rules against a parsed CODECO
|
|
40
|
+
* or COPRAR. Returns an array of diagnostics (empty = clean message).
|
|
41
|
+
*
|
|
42
|
+
* Rules implemented:
|
|
43
|
+
* - BAD_CHECK_DIGIT · ISO 6346 mod-11 fails on any EQD container number
|
|
44
|
+
* - BAD_BIC_FORMAT · EQD container ID not in 4-letter + 7-digit shape
|
|
45
|
+
* - BAD_LOCODE_FORMAT · LOC place doesn't match 5-char UN/LOCODE pattern
|
|
46
|
+
* - DTM_FORMAT · DTM format not 203 (SMDG mandates 203)
|
|
47
|
+
* - MISSING_NAD_CF · Required container operator party absent
|
|
48
|
+
* - EMPTY_BUT_HEAVY · EQD declared empty but gross weight exceeds tare
|
|
49
|
+
* - UNKNOWN_SIZETYPE · ISO 4-character size-type not in catalogue
|
|
50
|
+
* - UNT_COUNT_WRONG · UNT segment count doesn't match actual UNH→UNT count
|
|
51
|
+
* - CNT_EQD_MISMATCH · CNT+16 declared count != actual EQD count
|
|
52
|
+
* - REEFER_WITHOUT_TMP · R-type ISO size but no TMP segment
|
|
53
|
+
* - LOAD_BUT_EMPTY · COPRAR Load (BGM 45) but EQD declares empty
|
|
54
|
+
* - MISSING_VGM · Full container on Load order missing SOLAS VGM
|
|
55
|
+
* - CHARSET_LOWERCASE · UNB declares UNOA but body contains lowercase
|
|
56
|
+
*/
|
|
57
|
+
export declare function diagnoseSingle(parsed: ParsedMessage): Diagnostic[];
|
|
58
|
+
/**
|
|
59
|
+
* Cross-message reconciliation between a COPRAR and its matching CODECO.
|
|
60
|
+
* Returns container-by-container matches with field-level diffs and
|
|
61
|
+
* unmatched-container lists.
|
|
62
|
+
*
|
|
63
|
+
* Tolerances:
|
|
64
|
+
* - Gross weight: ±2%
|
|
65
|
+
* - VGM: ±5%
|
|
66
|
+
* - Reefer temperature: ±1°C
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import { parse, reconcile } from "@prefixcheck/edi";
|
|
71
|
+
* const coprar = parse(coprarText);
|
|
72
|
+
* const codeco = parse(codecoText);
|
|
73
|
+
* const report = reconcile(coprar, codeco);
|
|
74
|
+
* console.log(`${report.matched.length} matched, ${report.inCoprarOnly.length} expected but not gated`);
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function reconcile(coprar: ParsedMessage, codeco: ParsedMessage): ReconcileReport;
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,UAAU,EAEV,aAAa,EACb,WAAW,EACX,aAAa,EAEb,eAAe,EAEhB,MAAM,YAAY,CAAC;AAgCpB;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CASxD;AAGD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAmHhD,CAAC;AAGF,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEvC,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAoP/C,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuC7D;AAGD,eAAO,MAAM,MAAM,EAAE,aASpB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,aASpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAapE;AAED,mFAAmF;AACnF,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIpE;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAIpD;AAGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,EAAE,CAqPlE;AAqED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,GAAG,eAAe,CAwFvF"}
|