@packet-net/pdn-aprs 0.1.1 → 0.3.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.
Files changed (81) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/README.md +9 -5
  3. package/dist/builder.d.ts +33 -8
  4. package/dist/builder.d.ts.map +1 -1
  5. package/dist/builder.js +64 -10
  6. package/dist/builder.js.map +1 -1
  7. package/dist/bytes.d.ts.map +1 -1
  8. package/dist/bytes.js +2 -1
  9. package/dist/bytes.js.map +1 -1
  10. package/dist/codes.js +8 -8
  11. package/dist/codes.js.map +1 -1
  12. package/dist/decode/index.d.ts.map +1 -1
  13. package/dist/decode/index.js +8 -5
  14. package/dist/decode/index.js.map +1 -1
  15. package/dist/decode/message.d.ts +2 -0
  16. package/dist/decode/message.d.ts.map +1 -1
  17. package/dist/decode/message.js +59 -33
  18. package/dist/decode/message.js.map +1 -1
  19. package/dist/decode/other.d.ts +20 -2
  20. package/dist/decode/other.d.ts.map +1 -1
  21. package/dist/decode/other.js +110 -48
  22. package/dist/decode/other.js.map +1 -1
  23. package/dist/decode/positioned.d.ts +26 -2
  24. package/dist/decode/positioned.d.ts.map +1 -1
  25. package/dist/decode/positioned.js +145 -79
  26. package/dist/decode/positioned.js.map +1 -1
  27. package/dist/decode/reports.d.ts.map +1 -1
  28. package/dist/decode/reports.js +47 -5
  29. package/dist/decode/reports.js.map +1 -1
  30. package/dist/decoder.d.ts.map +1 -1
  31. package/dist/decoder.js +2 -4
  32. package/dist/decoder.js.map +1 -1
  33. package/dist/deviceid.d.ts +8 -2
  34. package/dist/deviceid.d.ts.map +1 -1
  35. package/dist/deviceid.js +28 -6
  36. package/dist/deviceid.js.map +1 -1
  37. package/dist/encode/common.d.ts +13 -2
  38. package/dist/encode/common.d.ts.map +1 -1
  39. package/dist/encode/common.js +36 -4
  40. package/dist/encode/common.js.map +1 -1
  41. package/dist/encode/index.d.ts.map +1 -1
  42. package/dist/encode/index.js +59 -22
  43. package/dist/encode/index.js.map +1 -1
  44. package/dist/encode/other.d.ts.map +1 -1
  45. package/dist/encode/other.js +45 -17
  46. package/dist/encode/other.js.map +1 -1
  47. package/dist/encode/position.d.ts +9 -3
  48. package/dist/encode/position.d.ts.map +1 -1
  49. package/dist/encode/position.js +258 -124
  50. package/dist/encode/position.js.map +1 -1
  51. package/dist/header.d.ts +5 -2
  52. package/dist/header.d.ts.map +1 -1
  53. package/dist/header.js +8 -3
  54. package/dist/header.js.map +1 -1
  55. package/dist/index.d.ts +1 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/neutral.d.ts.map +1 -1
  59. package/dist/neutral.js +22 -3
  60. package/dist/neutral.js.map +1 -1
  61. package/dist/types.d.ts +19 -9
  62. package/dist/types.d.ts.map +1 -1
  63. package/package.json +1 -1
  64. package/src/builder.ts +77 -14
  65. package/src/bytes.ts +2 -1
  66. package/src/codes.ts +8 -8
  67. package/src/decode/index.ts +7 -4
  68. package/src/decode/message.ts +54 -37
  69. package/src/decode/other.ts +116 -44
  70. package/src/decode/positioned.ts +159 -90
  71. package/src/decode/reports.ts +47 -4
  72. package/src/decoder.ts +2 -5
  73. package/src/deviceid.ts +29 -5
  74. package/src/encode/common.ts +34 -4
  75. package/src/encode/index.ts +57 -20
  76. package/src/encode/other.ts +39 -13
  77. package/src/encode/position.ts +261 -119
  78. package/src/header.ts +9 -2
  79. package/src/index.ts +1 -0
  80. package/src/neutral.ts +24 -3
  81. package/src/types.ts +20 -5
package/src/header.ts CHANGED
@@ -71,17 +71,24 @@ export function parseTnc2Header(line: Uint8Array, options: ParseOptions): Parsed
71
71
  }
72
72
  }
73
73
 
74
- /** Parses `SOURCE>DEST,PATH` (without the colon). Used for TNC2 lines and third-party headers. */
74
+ /** A third-party source: 1-9 printable ASCII characters (APRS12c ch. 17); `>` and `:` end it. */
75
+ const THIRD_PARTY_SOURCE = /^[\x20-\x7e]{1,9}$/;
76
+
77
+ /**
78
+ * Parses `SOURCE>DEST,PATH` (without the colon). Used for TNC2 lines and third-party headers,
79
+ * whose source need not be an APRS-IS address (`thirdParty`).
80
+ */
75
81
  export function parseHeaderText(
76
82
  header: string,
77
83
  options: ParseOptions,
78
84
  diags: Diagnostic[],
85
+ thirdParty = false,
79
86
  ): { source: string; destination: string; path: PathEntry[] } {
80
87
  const gt = header.indexOf('>');
81
88
  if (gt < 0) fail(diags, 'invalid-header');
82
89
  const source = header.slice(0, gt);
83
90
  if (source.length === 0) fail(diags, 'invalid-header');
84
- if (!APRS_IS_ADDRESS.test(source)) fail(diags, 'invalid-address');
91
+ if (!(thirdParty ? THIRD_PARTY_SOURCE : APRS_IS_ADDRESS).test(source)) fail(diags, 'invalid-address');
85
92
  const parts = header.slice(gt + 1).split(',');
86
93
  const destination = parts[0]!;
87
94
  if (destination.length === 0) tolerate(options, diags, 'empty-destination');
package/src/index.ts CHANGED
@@ -54,4 +54,5 @@ export {
54
54
  DEFAULT_DESTINATION,
55
55
  timestampOf,
56
56
  type BuiltPacket,
57
+ type WeatherInput,
57
58
  } from './builder.js';
package/src/neutral.ts CHANGED
@@ -3,7 +3,8 @@
3
3
  // sent. Used by the conformance tests and the differential dump, and handy for comparing this
4
4
  // library with another implementation.
5
5
 
6
- import { formatDiagnostic } from './diagnostics.js';
6
+ import type { DiagnosticCode } from './codes.js';
7
+ import { diagnostic, formatDiagnostic, type Diagnostic, type Severity } from './diagnostics.js';
7
8
  import type {
8
9
  AprsData,
9
10
  AprsPacket,
@@ -281,6 +282,7 @@ export function toNeutralData(d: AprsData): Neutral {
281
282
  put(o, 'altitude_m', d.altitudeM);
282
283
  put(o, 'time', d.time);
283
284
  put(o, 'waypoint', d.waypoint);
285
+ put(o, 'comment', d.comment);
284
286
  break;
285
287
  case 'maidenhead-beacon':
286
288
  put(o, 'locator', d.locator);
@@ -560,6 +562,7 @@ export function fromNeutralData(d: J): AprsData {
560
562
  opt(o, 'altitudeM', d.altitude_m);
561
563
  opt(o, 'time', d.time);
562
564
  opt(o, 'waypoint', d.waypoint);
565
+ opt(o, 'comment', d.comment);
563
566
  break;
564
567
  case 'maidenhead-beacon':
565
568
  o.locator = d.locator ?? '';
@@ -588,8 +591,26 @@ export function fromNeutralData(d: J): AprsData {
588
591
  case 'unrecognized':
589
592
  o.reason = d.reason;
590
593
  break;
591
- case 'third-party':
592
- throw new RangeError('third-party data cannot be built from the neutral form');
594
+ case 'third-party': {
595
+ // The inner packet as data: its information field is written from its data, and its
596
+ // diagnostics are kept, so one with a tolerated defect is refused, as the Encoding rule says.
597
+ const p: J = d.packet ?? {};
598
+ o.packet = {
599
+ source: p.source ?? '',
600
+ destination: p.destination ?? '',
601
+ path: ((p.path ?? []) as string[]).map((e) => (e.endsWith('*') ? { address: e.slice(0, -1), used: true } : { address: e, used: false })),
602
+ information: new Uint8Array(0),
603
+ data: fromNeutralData(p.data ?? { type: 'unrecognized', reason: 'empty' }),
604
+ diagnostics: ((p.diagnostics ?? []) as string[]).map(diagnosticFrom),
605
+ };
606
+ break;
607
+ }
593
608
  }
594
609
  return o as unknown as AprsData;
595
610
  }
611
+
612
+ /** A diagnostic from its neutral form, `severity:code`. */
613
+ function diagnosticFrom(text: string): Diagnostic {
614
+ const colon = text.indexOf(':');
615
+ return diagnostic(text.slice(0, colon) as Severity, text.slice(colon + 1) as DiagnosticCode);
616
+ }
package/src/types.ts CHANGED
@@ -136,7 +136,7 @@ export type DaoPrecision = 'none' | 'thousandths' | 'base91';
136
136
 
137
137
  /** The `!DAO!` datum and precision (APRS12c ch. 5). */
138
138
  export interface Dao {
139
- /** The datum letter, upper case (`W` is WGS84). */
139
+ /** The datum: a letter, upper case (`W` is WGS84), or a digit for a local datum. */
140
140
  readonly datum: string;
141
141
  readonly precision: DaoPrecision;
142
142
  }
@@ -146,7 +146,7 @@ export interface CommentTelemetry {
146
146
  readonly sequence: number;
147
147
  /** One to five analog values, 0-8280. */
148
148
  readonly analog: readonly number[];
149
- /** The eight digital bits as a number, B1 the least significant bit. */
149
+ /** The eight binary channels as a number, 0-255, B1 the least significant bit. */
150
150
  readonly digital?: number;
151
151
  }
152
152
 
@@ -419,7 +419,7 @@ export interface RawWeather {
419
419
  /** A raw NMEA sentence (`$`). */
420
420
  export interface NmeaSentence {
421
421
  readonly type: 'nmea';
422
- /** The sentence without the `$`. */
422
+ /** The sentence without the `$`, up to and including any `*hh` checksum. */
423
423
  readonly sentence: string;
424
424
  readonly hasChecksum?: boolean;
425
425
  readonly latitude?: number;
@@ -428,9 +428,11 @@ export interface NmeaSentence {
428
428
  readonly courseDegrees?: number;
429
429
  readonly speedKnots?: number;
430
430
  readonly altitudeM?: number;
431
- /** `HH:MM:SS`, with any fraction of a second. */
431
+ /** `HH:MM:SS`, with any fraction of a second as sent. */
432
432
  readonly time?: string;
433
433
  readonly waypoint?: string;
434
+ /** Text after the checksum (TinyTrack and FreeTrak send one), as sent. */
435
+ readonly comment?: string;
434
436
  }
435
437
 
436
438
  /** A Maidenhead locator beacon (`[`), obsolete. */
@@ -440,11 +442,24 @@ export interface MaidenheadBeacon {
440
442
  readonly comment?: string;
441
443
  }
442
444
 
445
+ /** A general query's footprint: a latitude, a longitude and a radius (APRS12c ch. 15). */
446
+ export interface QueryFootprint {
447
+ /** Degrees, north positive. */
448
+ readonly latitude: number;
449
+ /** Degrees, east positive. */
450
+ readonly longitude: number;
451
+ readonly radiusMiles: number;
452
+ /** The latitude as sent (` 34.0`, `-.1715`), with any leading space, so it can be written back the same. */
453
+ readonly latitudeText?: string;
454
+ /** The longitude as sent, so it can be written back the same. */
455
+ readonly longitudeText?: string;
456
+ }
457
+
443
458
  /** A general query (`?`). */
444
459
  export interface Query {
445
460
  readonly type: 'query';
446
461
  readonly queryType: string;
447
- readonly footprint?: { readonly latitude: number; readonly longitude: number; readonly radiusMiles: number };
462
+ readonly footprint?: QueryFootprint;
448
463
  }
449
464
 
450
465
  /** A station capability: a token, or a token and its value. */