@saber-usa/node-common 1.7.24-alpha.1 → 1.7.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saber-usa/node-common",
3
- "version": "1.7.24-alpha.1",
3
+ "version": "1.7.25",
4
4
  "description": "Common node functions for Saber",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/astro.js CHANGED
@@ -1382,7 +1382,7 @@ const GetElsetUdlFromTle = (
1382
1382
  try {
1383
1383
  const tleResult = validateTle(l1, l2);
1384
1384
  if (!tleResult.ok) {
1385
- throw new Error(tleResult.errors.join("; "));
1385
+ throw new Error(`${tleResult.errors.join("; ")}: ${l1} | ${l2}`);
1386
1386
  }
1387
1387
 
1388
1388
  const elset = {};
@@ -1,114 +1,114 @@
1
- import TLEValidator from "./TLEValidator.js";
2
- import {TLE_ERRORS} from "./tleErrors.js";
3
-
4
- /**
5
- * Validates multiple TLE lines, pairing line 1 with line 2.
6
- * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
7
- */
8
- class MultiLineTLEValidator {
9
- constructor() {
10
- this.reset();
11
- }
12
-
13
- reset() {
14
- this.recentLine = null;
15
- this.pairs = [];
16
- this.orphans = [];
17
- this.tleValidator = new TLEValidator();
18
- }
19
-
20
- validateLines(lines) {
21
- this.reset();
22
- for (const line of lines) {
23
- this.validateLine(line);
24
- }
25
- this.flushRecentLine();
26
- return this.getResults();
27
- }
28
-
29
- flushRecentLine() {
30
- if (this.recentLine === null) {
31
- return;
32
- }
33
- if (this.recentLine.startsWith("1 ")) {
34
- this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
35
- } else if (this.recentLine.startsWith("2 ")) {
36
- this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE2});
37
- } else {
38
- this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
39
- }
40
- this.recentLine = null;
41
- }
42
-
43
- validateLine(line = "") {
44
- const sanitized = this.sanitizeLine(line);
45
- if (sanitized === null) {
46
- return null;
47
- }
48
-
49
- if (this.recentLine === null) {
50
- this.recentLine = sanitized;
51
- return null;
52
- }
53
-
54
- if (this.recentLine.startsWith("1 ")) {
55
- if (sanitized.startsWith("2 ")) {
56
- this.recordPair(this.recentLine, sanitized);
57
- this.recentLine = null;
58
- } else {
59
- this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
60
- this.recentLine = sanitized;
61
- }
62
- return null;
63
- }
64
-
65
- if (this.recentLine.startsWith("2 ")) {
66
- this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE2});
67
- this.recentLine = sanitized;
68
- return null;
69
- }
70
-
71
- this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
72
- this.recentLine = sanitized;
73
- return null;
74
- }
75
-
76
- recordPair(line1, line2) {
77
- const tleStatus = this.tleValidator.validate(line1, line2);
78
- const errors = [];
79
- if (tleStatus.lineOneStatus !== null) {
80
- errors.push(tleStatus.lineOneStatus);
81
- }
82
- if (tleStatus.lineTwoStatus !== null) {
83
- errors.push(tleStatus.lineTwoStatus);
84
- }
85
- this.pairs.push({
86
- line1,
87
- line2,
88
- ok: errors.length === 0,
89
- errors,
90
- });
91
- }
92
-
93
- sanitizeLine(line) {
94
- if (line.startsWith("✅") || line.startsWith("🚩")) {
95
- return null;
96
- }
97
- if (line.includes("✅")) {
98
- return line.slice(0, line.indexOf("✅"));
99
- }
100
- if (line.includes("🚩")) {
101
- return line.slice(0, line.indexOf("🚩"));
102
- }
103
- return line;
104
- }
105
-
106
- getResults() {
107
- return {
108
- pairs: this.pairs,
109
- orphans: this.orphans,
110
- };
111
- }
112
- }
113
-
114
- export default MultiLineTLEValidator;
1
+ import TLEValidator from "./TLEValidator.js";
2
+ import {TLE_ERRORS} from "./tleErrors.js";
3
+
4
+ /**
5
+ * Validates multiple TLE lines, pairing line 1 with line 2.
6
+ * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
7
+ */
8
+ class MultiLineTLEValidator {
9
+ constructor() {
10
+ this.reset();
11
+ }
12
+
13
+ reset() {
14
+ this.recentLine = null;
15
+ this.pairs = [];
16
+ this.orphans = [];
17
+ this.tleValidator = new TLEValidator();
18
+ }
19
+
20
+ validateLines(lines) {
21
+ this.reset();
22
+ for (const line of lines) {
23
+ this.validateLine(line);
24
+ }
25
+ this.flushRecentLine();
26
+ return this.getResults();
27
+ }
28
+
29
+ flushRecentLine() {
30
+ if (this.recentLine === null) {
31
+ return;
32
+ }
33
+ if (this.recentLine.startsWith("1 ")) {
34
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
35
+ } else if (this.recentLine.startsWith("2 ")) {
36
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE2});
37
+ } else {
38
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
39
+ }
40
+ this.recentLine = null;
41
+ }
42
+
43
+ validateLine(line = "") {
44
+ const sanitized = this.sanitizeLine(line);
45
+ if (sanitized === null) {
46
+ return null;
47
+ }
48
+
49
+ if (this.recentLine === null) {
50
+ this.recentLine = sanitized;
51
+ return null;
52
+ }
53
+
54
+ if (this.recentLine.startsWith("1 ")) {
55
+ if (sanitized.startsWith("2 ")) {
56
+ this.recordPair(this.recentLine, sanitized);
57
+ this.recentLine = null;
58
+ } else {
59
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
60
+ this.recentLine = sanitized;
61
+ }
62
+ return null;
63
+ }
64
+
65
+ if (this.recentLine.startsWith("2 ")) {
66
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE2});
67
+ this.recentLine = sanitized;
68
+ return null;
69
+ }
70
+
71
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
72
+ this.recentLine = sanitized;
73
+ return null;
74
+ }
75
+
76
+ recordPair(line1, line2) {
77
+ const tleStatus = this.tleValidator.validate(line1, line2);
78
+ const errors = [];
79
+ if (tleStatus.lineOneStatus !== null) {
80
+ errors.push(tleStatus.lineOneStatus);
81
+ }
82
+ if (tleStatus.lineTwoStatus !== null) {
83
+ errors.push(tleStatus.lineTwoStatus);
84
+ }
85
+ this.pairs.push({
86
+ line1,
87
+ line2,
88
+ ok: errors.length === 0,
89
+ errors,
90
+ });
91
+ }
92
+
93
+ sanitizeLine(line) {
94
+ if (line.startsWith("✅") || line.startsWith("🚩")) {
95
+ return null;
96
+ }
97
+ if (line.includes("✅")) {
98
+ return line.slice(0, line.indexOf("✅"));
99
+ }
100
+ if (line.includes("🚩")) {
101
+ return line.slice(0, line.indexOf("🚩"));
102
+ }
103
+ return line;
104
+ }
105
+
106
+ getResults() {
107
+ return {
108
+ pairs: this.pairs,
109
+ orphans: this.orphans,
110
+ };
111
+ }
112
+ }
113
+
114
+ export default MultiLineTLEValidator;
@@ -1,135 +1,135 @@
1
- import {formatChecksumError, formatLengthError, TLE_ERRORS} from "./tleErrors.js";
2
-
3
- /**
4
- * NORAD TLE line-pair validator.
5
- * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
6
- */
7
- class TLEValidator {
8
- constructor() {
9
- this.lineOneRegexCatalogNumber = /[0-Z]{5}[CSU]/;
10
- this.lineOneRegexInternationalDesignator = / (\d{5}[A-Z][ A-Z]{2}|\d{5}[ A-Z]{2}[A-Z]| {8})/;
11
- this.lineOneRegexEpoch = / \d{5}\.\d{8}/;
12
- this.lineOneRegexDMeanMotion = / [ +-]\.\d{8}/;
13
- this.lineOneRegexDDMeanMotion = / [ +-]\d{5}[-+]\d/;
14
- this.lineOneRegexBSTAR = / [ +-]\d{5}[-+]\d/;
15
- this.lineOneRegexEphemType = / [0-5]/;
16
- this.lineOneRegexSetNumber = / [ \d]{3}\d/;
17
-
18
- this.lineTwoRegexCatalogNumber = /[0-Z]{5}/;
19
- this.lineTwoRegexInclination = / [ \d]{3}\.\d{4}/;
20
- this.lineTwoRegexRAAN = / [ \d]{3}\.\d{4}/;
21
- this.lineTwoRegexEccentricity = / \d{7}/;
22
- this.lineTwoRegexArgumentOfPerigee = / [ \d]{3}\.\d{4}/;
23
- this.lineTwoRegexMeanAnomaly = / [ \d]{3}\.\d{4}/;
24
- this.lineTwoRegexMeanMotion = / [ \d]{2}\.\d{8}/;
25
- this.lineTwoRegexRevNumber = /[ \d]{4}\d/;
26
- }
27
-
28
- computeChecksum(line) {
29
- let sum = 0;
30
- for (let i = 0; i < 68; i += 1) {
31
- const char = line[i];
32
- const val = Number.parseInt(char, 10);
33
- if (!Number.isNaN(val)) {
34
- sum += val;
35
- } else if (char === "-") {
36
- sum += 1;
37
- }
38
- }
39
- return sum % 10;
40
- }
41
-
42
- validate(lineOne, lineTwo) {
43
- const lineOneStatus = this.validateLineOne(lineOne);
44
- const lineTwoStatus = this.validateLineTwo(lineTwo);
45
- if (lineOneStatus === null
46
- && lineTwoStatus === null
47
- && lineOne.slice(2, 7) !== lineTwo.slice(2, 7)) {
48
- return {
49
- lineOneStatus: null,
50
- lineTwoStatus: TLE_ERRORS.CATALOG_MISMATCH,
51
- };
52
- }
53
- return {lineOneStatus, lineTwoStatus};
54
- }
55
-
56
- validateLineOne(line) {
57
- if (line.length < 69) {
58
- return formatLengthError(TLE_ERRORS.LINE1_LENGTH, line.length);
59
- }
60
- if (!this.lineOneRegexCatalogNumber.test(line.slice(2, 8))) {
61
- return TLE_ERRORS.LINE1_CATALOG_NUMBER;
62
- }
63
- if (!this.lineOneRegexInternationalDesignator.test(line.slice(8, 17))) {
64
- return TLE_ERRORS.LINE1_INTERNATIONAL_DESIGNATOR;
65
- }
66
- if (!this.lineOneRegexEpoch.test(line.slice(17, 32))) {
67
- return TLE_ERRORS.LINE1_EPOCH;
68
- }
69
- if (!this.lineOneRegexDMeanMotion.test(line.slice(32, 43))) {
70
- return TLE_ERRORS.LINE1_D_MEAN_MOTION;
71
- }
72
- if (!this.lineOneRegexDDMeanMotion.test(line.slice(43, 52))) {
73
- return TLE_ERRORS.LINE1_DD_MEAN_MOTION;
74
- }
75
- if (!this.lineOneRegexBSTAR.test(line.slice(52, 61))) {
76
- return TLE_ERRORS.LINE1_BSTAR;
77
- }
78
- if (!this.lineOneRegexEphemType.test(line.slice(61, 63))) {
79
- return TLE_ERRORS.LINE1_EPHEM_TYPE;
80
- }
81
- if (!this.lineOneRegexSetNumber.test(line.slice(63, 68))) {
82
- return TLE_ERRORS.LINE1_SET_NUMBER;
83
- }
84
- if (line.length > 69) {
85
- return TLE_ERRORS.LINE1_EXTRA_CHARS;
86
- }
87
-
88
- const checksum = this.computeChecksum(line);
89
- if (checksum !== Number.parseInt(line[68], 10)) {
90
- return formatChecksumError(TLE_ERRORS.LINE1_CHECKSUM, checksum);
91
- }
92
- return null;
93
- }
94
-
95
- validateLineTwo(line) {
96
- if (line.length < 69) {
97
- return formatLengthError(TLE_ERRORS.LINE2_LENGTH, line.length);
98
- }
99
- if (!this.lineTwoRegexCatalogNumber.test(line.slice(2, 7))) {
100
- return TLE_ERRORS.LINE2_CATALOG_NUMBER;
101
- }
102
- if (!this.lineTwoRegexInclination.test(line.slice(7, 16))) {
103
- return TLE_ERRORS.LINE2_INCLINATION;
104
- }
105
- if (!this.lineTwoRegexRAAN.test(line.slice(16, 25))) {
106
- return TLE_ERRORS.LINE2_RAAN;
107
- }
108
- if (!this.lineTwoRegexEccentricity.test(line.slice(25, 33))) {
109
- return TLE_ERRORS.LINE2_ECCENTRICITY;
110
- }
111
- if (!this.lineTwoRegexArgumentOfPerigee.test(line.slice(33, 42))) {
112
- return TLE_ERRORS.LINE2_ARGUMENT_OF_PERIGEE;
113
- }
114
- if (!this.lineTwoRegexMeanAnomaly.test(line.slice(42, 51))) {
115
- return TLE_ERRORS.LINE2_MEAN_ANOMALY;
116
- }
117
- if (!this.lineTwoRegexMeanMotion.test(line.slice(51, 63))) {
118
- return TLE_ERRORS.LINE2_MEAN_MOTION;
119
- }
120
- if (!this.lineTwoRegexRevNumber.test(line.slice(63, 68))) {
121
- return TLE_ERRORS.LINE2_REV_NUMBER;
122
- }
123
- if (line.length > 69) {
124
- return TLE_ERRORS.LINE2_EXTRA_CHARS;
125
- }
126
-
127
- const checksum = this.computeChecksum(line);
128
- if (checksum !== Number.parseInt(line[68], 10)) {
129
- return formatChecksumError(TLE_ERRORS.LINE2_CHECKSUM, checksum);
130
- }
131
- return null;
132
- }
133
- }
134
-
135
- export default TLEValidator;
1
+ import {formatChecksumError, formatLengthError, TLE_ERRORS} from "./tleErrors.js";
2
+
3
+ /**
4
+ * NORAD TLE line-pair validator.
5
+ * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
6
+ */
7
+ class TLEValidator {
8
+ constructor() {
9
+ this.lineOneRegexCatalogNumber = /[0-Z]{5}[CSU]/;
10
+ this.lineOneRegexInternationalDesignator = / (\d{5}[A-Z][ A-Z]{2}|\d{5}[ A-Z]{2}[A-Z]| {8})/;
11
+ this.lineOneRegexEpoch = / \d{5}\.\d{8}/;
12
+ this.lineOneRegexDMeanMotion = / [ +-]\.\d{8}/;
13
+ this.lineOneRegexDDMeanMotion = / [ +-]\d{5}[-+]\d/;
14
+ this.lineOneRegexBSTAR = / [ +-]\d{5}[-+]\d/;
15
+ this.lineOneRegexEphemType = / [0-5]/;
16
+ this.lineOneRegexSetNumber = / [ \d]{3}\d/;
17
+
18
+ this.lineTwoRegexCatalogNumber = /[0-Z]{5}/;
19
+ this.lineTwoRegexInclination = / [ \d]{3}\.\d{4}/;
20
+ this.lineTwoRegexRAAN = / [ \d]{3}\.\d{4}/;
21
+ this.lineTwoRegexEccentricity = / \d{7}/;
22
+ this.lineTwoRegexArgumentOfPerigee = / [ \d]{3}\.\d{4}/;
23
+ this.lineTwoRegexMeanAnomaly = / [ \d]{3}\.\d{4}/;
24
+ this.lineTwoRegexMeanMotion = / [ \d]{2}\.\d{8}/;
25
+ this.lineTwoRegexRevNumber = /[ \d]{4}\d/;
26
+ }
27
+
28
+ computeChecksum(line) {
29
+ let sum = 0;
30
+ for (let i = 0; i < 68; i += 1) {
31
+ const char = line[i];
32
+ const val = Number.parseInt(char, 10);
33
+ if (!Number.isNaN(val)) {
34
+ sum += val;
35
+ } else if (char === "-") {
36
+ sum += 1;
37
+ }
38
+ }
39
+ return sum % 10;
40
+ }
41
+
42
+ validate(lineOne, lineTwo) {
43
+ const lineOneStatus = this.validateLineOne(lineOne);
44
+ const lineTwoStatus = this.validateLineTwo(lineTwo);
45
+ if (lineOneStatus === null
46
+ && lineTwoStatus === null
47
+ && lineOne.slice(2, 7) !== lineTwo.slice(2, 7)) {
48
+ return {
49
+ lineOneStatus: null,
50
+ lineTwoStatus: TLE_ERRORS.CATALOG_MISMATCH,
51
+ };
52
+ }
53
+ return {lineOneStatus, lineTwoStatus};
54
+ }
55
+
56
+ validateLineOne(line) {
57
+ if (line.length < 69) {
58
+ return formatLengthError(TLE_ERRORS.LINE1_LENGTH, line.length);
59
+ }
60
+ if (!this.lineOneRegexCatalogNumber.test(line.slice(2, 8))) {
61
+ return TLE_ERRORS.LINE1_CATALOG_NUMBER;
62
+ }
63
+ if (!this.lineOneRegexInternationalDesignator.test(line.slice(8, 17))) {
64
+ return TLE_ERRORS.LINE1_INTERNATIONAL_DESIGNATOR;
65
+ }
66
+ if (!this.lineOneRegexEpoch.test(line.slice(17, 32))) {
67
+ return TLE_ERRORS.LINE1_EPOCH;
68
+ }
69
+ if (!this.lineOneRegexDMeanMotion.test(line.slice(32, 43))) {
70
+ return TLE_ERRORS.LINE1_D_MEAN_MOTION;
71
+ }
72
+ if (!this.lineOneRegexDDMeanMotion.test(line.slice(43, 52))) {
73
+ return TLE_ERRORS.LINE1_DD_MEAN_MOTION;
74
+ }
75
+ if (!this.lineOneRegexBSTAR.test(line.slice(52, 61))) {
76
+ return TLE_ERRORS.LINE1_BSTAR;
77
+ }
78
+ if (!this.lineOneRegexEphemType.test(line.slice(61, 63))) {
79
+ return TLE_ERRORS.LINE1_EPHEM_TYPE;
80
+ }
81
+ if (!this.lineOneRegexSetNumber.test(line.slice(63, 68))) {
82
+ return TLE_ERRORS.LINE1_SET_NUMBER;
83
+ }
84
+ if (line.length > 69) {
85
+ return TLE_ERRORS.LINE1_EXTRA_CHARS;
86
+ }
87
+
88
+ const checksum = this.computeChecksum(line);
89
+ if (checksum !== Number.parseInt(line[68], 10)) {
90
+ return formatChecksumError(TLE_ERRORS.LINE1_CHECKSUM, checksum);
91
+ }
92
+ return null;
93
+ }
94
+
95
+ validateLineTwo(line) {
96
+ if (line.length < 69) {
97
+ return formatLengthError(TLE_ERRORS.LINE2_LENGTH, line.length);
98
+ }
99
+ if (!this.lineTwoRegexCatalogNumber.test(line.slice(2, 7))) {
100
+ return TLE_ERRORS.LINE2_CATALOG_NUMBER;
101
+ }
102
+ if (!this.lineTwoRegexInclination.test(line.slice(7, 16))) {
103
+ return TLE_ERRORS.LINE2_INCLINATION;
104
+ }
105
+ if (!this.lineTwoRegexRAAN.test(line.slice(16, 25))) {
106
+ return TLE_ERRORS.LINE2_RAAN;
107
+ }
108
+ if (!this.lineTwoRegexEccentricity.test(line.slice(25, 33))) {
109
+ return TLE_ERRORS.LINE2_ECCENTRICITY;
110
+ }
111
+ if (!this.lineTwoRegexArgumentOfPerigee.test(line.slice(33, 42))) {
112
+ return TLE_ERRORS.LINE2_ARGUMENT_OF_PERIGEE;
113
+ }
114
+ if (!this.lineTwoRegexMeanAnomaly.test(line.slice(42, 51))) {
115
+ return TLE_ERRORS.LINE2_MEAN_ANOMALY;
116
+ }
117
+ if (!this.lineTwoRegexMeanMotion.test(line.slice(51, 63))) {
118
+ return TLE_ERRORS.LINE2_MEAN_MOTION;
119
+ }
120
+ if (!this.lineTwoRegexRevNumber.test(line.slice(63, 68))) {
121
+ return TLE_ERRORS.LINE2_REV_NUMBER;
122
+ }
123
+ if (line.length > 69) {
124
+ return TLE_ERRORS.LINE2_EXTRA_CHARS;
125
+ }
126
+
127
+ const checksum = this.computeChecksum(line);
128
+ if (checksum !== Number.parseInt(line[68], 10)) {
129
+ return formatChecksumError(TLE_ERRORS.LINE2_CHECKSUM, checksum);
130
+ }
131
+ return null;
132
+ }
133
+ }
134
+
135
+ export default TLEValidator;
@@ -1,36 +1,36 @@
1
- /**
2
- * TLE validation error message constants.
3
- * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
4
- */
5
- export const TLE_ERRORS = {
6
- LINE1_LENGTH: "TLE line 1 must be 69 characters",
7
- LINE2_LENGTH: "TLE line 2 must be 69 characters",
8
- LINE1_EXTRA_CHARS: "TLE line 1: extra character(s) detected",
9
- LINE2_EXTRA_CHARS: "TLE line 2: extra character(s) detected",
10
- LINE1_CATALOG_NUMBER: "TLE line 1: fix catalog number",
11
- LINE1_INTERNATIONAL_DESIGNATOR: "TLE line 1: fix international designator or leave it blank",
12
- LINE1_EPOCH: "TLE line 1: fix epoch",
13
- LINE1_D_MEAN_MOTION: "TLE line 1: fix first derivative of mean motion",
14
- LINE1_DD_MEAN_MOTION: "TLE line 1: fix second derivative of mean motion",
15
- LINE1_BSTAR: "TLE line 1: fix BSTAR",
16
- LINE1_EPHEM_TYPE: "TLE line 1: ephemeris type should be zero",
17
- LINE1_SET_NUMBER: "TLE line 1: fix element set number",
18
- LINE1_CHECKSUM: "TLE line 1: checksum should be",
19
- LINE2_CATALOG_NUMBER: "TLE line 2: fix catalog number",
20
- LINE2_INCLINATION: "TLE line 2: fix inclination",
21
- LINE2_RAAN: "TLE line 2: fix right ascension",
22
- LINE2_ECCENTRICITY: "TLE line 2: fix eccentricity",
23
- LINE2_ARGUMENT_OF_PERIGEE: "TLE line 2: fix argument of perigee",
24
- LINE2_MEAN_ANOMALY: "TLE line 2: fix mean anomaly",
25
- LINE2_MEAN_MOTION: "TLE line 2: fix mean motion",
26
- LINE2_REV_NUMBER: "TLE line 2: fix revolution number",
27
- LINE2_CHECKSUM: "TLE line 2: checksum should be",
28
- CATALOG_MISMATCH: "TLE catalog numbers must match between lines",
29
- ORPHAN_LINE1: "Found line 1, missing line 2",
30
- ORPHAN_LINE2: "Found line 2, missing line one",
31
- PROPAGATE_FAILED: "TLE propagation failed",
32
- };
33
-
34
- export const formatLengthError = (baseMessage, length) => `${baseMessage} (got ${length})`;
35
-
36
- export const formatChecksumError = (baseMessage, checksum) => `${baseMessage} ${checksum}`;
1
+ /**
2
+ * TLE validation error message constants.
3
+ * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
4
+ */
5
+ export const TLE_ERRORS = {
6
+ LINE1_LENGTH: "TLE line 1 must be 69 characters",
7
+ LINE2_LENGTH: "TLE line 2 must be 69 characters",
8
+ LINE1_EXTRA_CHARS: "TLE line 1: extra character(s) detected",
9
+ LINE2_EXTRA_CHARS: "TLE line 2: extra character(s) detected",
10
+ LINE1_CATALOG_NUMBER: "TLE line 1: fix catalog number",
11
+ LINE1_INTERNATIONAL_DESIGNATOR: "TLE line 1: fix international designator or leave it blank",
12
+ LINE1_EPOCH: "TLE line 1: fix epoch",
13
+ LINE1_D_MEAN_MOTION: "TLE line 1: fix first derivative of mean motion",
14
+ LINE1_DD_MEAN_MOTION: "TLE line 1: fix second derivative of mean motion",
15
+ LINE1_BSTAR: "TLE line 1: fix BSTAR",
16
+ LINE1_EPHEM_TYPE: "TLE line 1: ephemeris type should be zero",
17
+ LINE1_SET_NUMBER: "TLE line 1: fix element set number",
18
+ LINE1_CHECKSUM: "TLE line 1: checksum should be",
19
+ LINE2_CATALOG_NUMBER: "TLE line 2: fix catalog number",
20
+ LINE2_INCLINATION: "TLE line 2: fix inclination",
21
+ LINE2_RAAN: "TLE line 2: fix right ascension",
22
+ LINE2_ECCENTRICITY: "TLE line 2: fix eccentricity",
23
+ LINE2_ARGUMENT_OF_PERIGEE: "TLE line 2: fix argument of perigee",
24
+ LINE2_MEAN_ANOMALY: "TLE line 2: fix mean anomaly",
25
+ LINE2_MEAN_MOTION: "TLE line 2: fix mean motion",
26
+ LINE2_REV_NUMBER: "TLE line 2: fix revolution number",
27
+ LINE2_CHECKSUM: "TLE line 2: checksum should be",
28
+ CATALOG_MISMATCH: "TLE catalog numbers must match between lines",
29
+ ORPHAN_LINE1: "Found line 1, missing line 2",
30
+ ORPHAN_LINE2: "Found line 2, missing line one",
31
+ PROPAGATE_FAILED: "TLE propagation failed",
32
+ };
33
+
34
+ export const formatLengthError = (baseMessage, length) => `${baseMessage} (got ${length})`;
35
+
36
+ export const formatChecksumError = (baseMessage, checksum) => `${baseMessage} ${checksum}`;