@tomgiee/tsdp 1.0.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 +124 -0
- package/dist/src/builder/media-builder.d.ts +221 -0
- package/dist/src/builder/media-builder.d.ts.map +1 -0
- package/dist/src/builder/media-builder.js +385 -0
- package/dist/src/builder/session-builder.d.ts +195 -0
- package/dist/src/builder/session-builder.d.ts.map +1 -0
- package/dist/src/builder/session-builder.js +366 -0
- package/dist/src/index.d.ts +67 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +250 -0
- package/dist/src/parser/attribute-parser.d.ts +100 -0
- package/dist/src/parser/attribute-parser.d.ts.map +1 -0
- package/dist/src/parser/attribute-parser.js +217 -0
- package/dist/src/parser/field-parser.d.ts +124 -0
- package/dist/src/parser/field-parser.d.ts.map +1 -0
- package/dist/src/parser/field-parser.js +335 -0
- package/dist/src/parser/media-parser.d.ts +45 -0
- package/dist/src/parser/media-parser.d.ts.map +1 -0
- package/dist/src/parser/media-parser.js +157 -0
- package/dist/src/parser/primitive-parser.d.ts +138 -0
- package/dist/src/parser/primitive-parser.d.ts.map +1 -0
- package/dist/src/parser/primitive-parser.js +316 -0
- package/dist/src/parser/scanner.d.ts +142 -0
- package/dist/src/parser/scanner.d.ts.map +1 -0
- package/dist/src/parser/scanner.js +284 -0
- package/dist/src/parser/session-parser.d.ts +35 -0
- package/dist/src/parser/session-parser.d.ts.map +1 -0
- package/dist/src/parser/session-parser.js +207 -0
- package/dist/src/parser/time-parser.d.ts +74 -0
- package/dist/src/parser/time-parser.d.ts.map +1 -0
- package/dist/src/parser/time-parser.js +168 -0
- package/dist/src/serializer/attribute-serializer.d.ts +18 -0
- package/dist/src/serializer/attribute-serializer.d.ts.map +1 -0
- package/dist/src/serializer/attribute-serializer.js +34 -0
- package/dist/src/serializer/field-serializer.d.ts +112 -0
- package/dist/src/serializer/field-serializer.d.ts.map +1 -0
- package/dist/src/serializer/field-serializer.js +212 -0
- package/dist/src/serializer/media-serializer.d.ts +31 -0
- package/dist/src/serializer/media-serializer.d.ts.map +1 -0
- package/dist/src/serializer/media-serializer.js +83 -0
- package/dist/src/serializer/session-serializer.d.ts +29 -0
- package/dist/src/serializer/session-serializer.d.ts.map +1 -0
- package/dist/src/serializer/session-serializer.js +99 -0
- package/dist/src/serializer/time-serializer.d.ts +46 -0
- package/dist/src/serializer/time-serializer.d.ts.map +1 -0
- package/dist/src/serializer/time-serializer.js +86 -0
- package/dist/src/types/attributes.d.ts +318 -0
- package/dist/src/types/attributes.d.ts.map +1 -0
- package/dist/src/types/attributes.js +225 -0
- package/dist/src/types/errors.d.ts +129 -0
- package/dist/src/types/errors.d.ts.map +1 -0
- package/dist/src/types/errors.js +186 -0
- package/dist/src/types/fields.d.ts +100 -0
- package/dist/src/types/fields.d.ts.map +1 -0
- package/dist/src/types/fields.js +48 -0
- package/dist/src/types/media.d.ts +148 -0
- package/dist/src/types/media.d.ts.map +1 -0
- package/dist/src/types/media.js +137 -0
- package/dist/src/types/network.d.ts +136 -0
- package/dist/src/types/network.d.ts.map +1 -0
- package/dist/src/types/network.js +130 -0
- package/dist/src/types/primitives.d.ts +193 -0
- package/dist/src/types/primitives.d.ts.map +1 -0
- package/dist/src/types/primitives.js +195 -0
- package/dist/src/types/session.d.ts +122 -0
- package/dist/src/types/session.d.ts.map +1 -0
- package/dist/src/types/session.js +81 -0
- package/dist/src/types/time.d.ts +129 -0
- package/dist/src/types/time.d.ts.map +1 -0
- package/dist/src/types/time.js +84 -0
- package/dist/src/utils/address-parser.d.ts +100 -0
- package/dist/src/utils/address-parser.d.ts.map +1 -0
- package/dist/src/utils/address-parser.js +338 -0
- package/dist/src/utils/format-validators.d.ts +77 -0
- package/dist/src/utils/format-validators.d.ts.map +1 -0
- package/dist/src/utils/format-validators.js +504 -0
- package/dist/src/utils/line-reader.d.ts +84 -0
- package/dist/src/utils/line-reader.d.ts.map +1 -0
- package/dist/src/utils/line-reader.js +169 -0
- package/dist/src/utils/time-converter.d.ts +99 -0
- package/dist/src/utils/time-converter.d.ts.map +1 -0
- package/dist/src/utils/time-converter.js +195 -0
- package/dist/src/validator/media-validator.d.ts +27 -0
- package/dist/src/validator/media-validator.d.ts.map +1 -0
- package/dist/src/validator/media-validator.js +241 -0
- package/dist/src/validator/semantic-validator.d.ts +47 -0
- package/dist/src/validator/semantic-validator.d.ts.map +1 -0
- package/dist/src/validator/semantic-validator.js +207 -0
- package/dist/src/validator/session-validator.d.ts +36 -0
- package/dist/src/validator/session-validator.d.ts.map +1 -0
- package/dist/src/validator/session-validator.js +280 -0
- package/dist/tests/integration/round-trip.test.d.ts +5 -0
- package/dist/tests/integration/round-trip.test.d.ts.map +1 -0
- package/dist/tests/integration/round-trip.test.js +320 -0
- package/dist/tests/integration/voip-examples.test.d.ts +5 -0
- package/dist/tests/integration/voip-examples.test.d.ts.map +1 -0
- package/dist/tests/integration/voip-examples.test.js +361 -0
- package/dist/tests/unit/builder/media-builder.test.d.ts +5 -0
- package/dist/tests/unit/builder/media-builder.test.d.ts.map +1 -0
- package/dist/tests/unit/builder/media-builder.test.js +524 -0
- package/dist/tests/unit/builder/session-builder.test.d.ts +5 -0
- package/dist/tests/unit/builder/session-builder.test.d.ts.map +1 -0
- package/dist/tests/unit/builder/session-builder.test.js +367 -0
- package/dist/tests/unit/parser/attribute-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/attribute-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/attribute-parser.test.js +319 -0
- package/dist/tests/unit/parser/field-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/field-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/field-parser.test.js +355 -0
- package/dist/tests/unit/parser/media-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/media-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/media-parser.test.js +241 -0
- package/dist/tests/unit/parser/primitive-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/primitive-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/primitive-parser.test.js +261 -0
- package/dist/tests/unit/parser/scanner.test.d.ts +5 -0
- package/dist/tests/unit/parser/scanner.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/scanner.test.js +241 -0
- package/dist/tests/unit/parser/session-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/session-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/session-parser.test.js +346 -0
- package/dist/tests/unit/parser/time-parser.test.d.ts +5 -0
- package/dist/tests/unit/parser/time-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/parser/time-parser.test.js +173 -0
- package/dist/tests/unit/serializer/attribute-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/attribute-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/attribute-serializer.test.js +78 -0
- package/dist/tests/unit/serializer/field-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/field-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/field-serializer.test.js +159 -0
- package/dist/tests/unit/serializer/media-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/media-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/media-serializer.test.js +155 -0
- package/dist/tests/unit/serializer/session-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/session-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/session-serializer.test.js +317 -0
- package/dist/tests/unit/serializer/time-serializer.test.d.ts +5 -0
- package/dist/tests/unit/serializer/time-serializer.test.d.ts.map +1 -0
- package/dist/tests/unit/serializer/time-serializer.test.js +115 -0
- package/dist/tests/unit/types/errors.test.d.ts +5 -0
- package/dist/tests/unit/types/errors.test.d.ts.map +1 -0
- package/dist/tests/unit/types/errors.test.js +127 -0
- package/dist/tests/unit/types/network.test.d.ts +5 -0
- package/dist/tests/unit/types/network.test.d.ts.map +1 -0
- package/dist/tests/unit/types/network.test.js +132 -0
- package/dist/tests/unit/types/primitives.test.d.ts +5 -0
- package/dist/tests/unit/types/primitives.test.d.ts.map +1 -0
- package/dist/tests/unit/types/primitives.test.js +108 -0
- package/dist/tests/unit/utils/address-parser.test.d.ts +5 -0
- package/dist/tests/unit/utils/address-parser.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/address-parser.test.js +203 -0
- package/dist/tests/unit/utils/format-validators.test.d.ts +5 -0
- package/dist/tests/unit/utils/format-validators.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/format-validators.test.js +224 -0
- package/dist/tests/unit/utils/line-reader.test.d.ts +5 -0
- package/dist/tests/unit/utils/line-reader.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/line-reader.test.js +157 -0
- package/dist/tests/unit/utils/time-converter.test.d.ts +5 -0
- package/dist/tests/unit/utils/time-converter.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/time-converter.test.js +190 -0
- package/dist/tests/unit/validator/media-validator.test.d.ts +5 -0
- package/dist/tests/unit/validator/media-validator.test.d.ts.map +1 -0
- package/dist/tests/unit/validator/media-validator.test.js +313 -0
- package/dist/tests/unit/validator/semantic-validator.test.d.ts +5 -0
- package/dist/tests/unit/validator/semantic-validator.test.d.ts.map +1 -0
- package/dist/tests/unit/validator/semantic-validator.test.js +262 -0
- package/dist/tests/unit/validator/session-validator.test.d.ts +5 -0
- package/dist/tests/unit/validator/session-validator.test.d.ts.map +1 -0
- package/dist/tests/unit/validator/session-validator.test.js +447 -0
- package/package.json +50 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time description types for SDP (RFC 8866)
|
|
3
|
+
*
|
|
4
|
+
* Defines types for timing, repeat times, and timezone adjustments.
|
|
5
|
+
*/
|
|
6
|
+
import { NtpTime, TypedTime } from './primitives';
|
|
7
|
+
/**
|
|
8
|
+
* Time Description (RFC 8866 Section 5.9-5.11)
|
|
9
|
+
*
|
|
10
|
+
* A time description consists of:
|
|
11
|
+
* - One timing field (t=)
|
|
12
|
+
* - Zero or more repeat fields (r=)
|
|
13
|
+
* - Zero or one timezone field (z=)
|
|
14
|
+
*
|
|
15
|
+
* At least one time description MUST be present in every session description.
|
|
16
|
+
*/
|
|
17
|
+
export interface TimeDescription {
|
|
18
|
+
/**
|
|
19
|
+
* Timing field (required)
|
|
20
|
+
*/
|
|
21
|
+
readonly timing: Timing;
|
|
22
|
+
/**
|
|
23
|
+
* Repeat fields (optional, multiple allowed)
|
|
24
|
+
*/
|
|
25
|
+
readonly repeats: readonly Repeat[];
|
|
26
|
+
/**
|
|
27
|
+
* Timezone field (optional, only one allowed)
|
|
28
|
+
*/
|
|
29
|
+
readonly timezone?: Timezone;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Timing field (RFC 8866 Section 5.9)
|
|
33
|
+
*
|
|
34
|
+
* Format: t=<start-time> <stop-time>
|
|
35
|
+
*
|
|
36
|
+
* Specifies the start and stop times for a session.
|
|
37
|
+
* Times are in NTP format (seconds since Jan 1, 1900 00:00:00 UTC).
|
|
38
|
+
* A value of 0 means the session is unbounded or permanent.
|
|
39
|
+
*/
|
|
40
|
+
export interface Timing {
|
|
41
|
+
/**
|
|
42
|
+
* Start time of the session (NTP timestamp)
|
|
43
|
+
* 0 means the session is not bounded
|
|
44
|
+
*/
|
|
45
|
+
readonly startTime: NtpTime;
|
|
46
|
+
/**
|
|
47
|
+
* Stop time of the session (NTP timestamp)
|
|
48
|
+
* 0 means the session is not bounded
|
|
49
|
+
*/
|
|
50
|
+
readonly stopTime: NtpTime;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Repeat field (RFC 8866 Section 5.10)
|
|
54
|
+
*
|
|
55
|
+
* Format: r=<repeat-interval> <active-duration> <offsets-from-start-time>
|
|
56
|
+
*
|
|
57
|
+
* Specifies repeat times for a session.
|
|
58
|
+
* For example, a session that repeats daily for 1 hour starting at 10am.
|
|
59
|
+
*/
|
|
60
|
+
export interface Repeat {
|
|
61
|
+
/**
|
|
62
|
+
* Interval between repetitions
|
|
63
|
+
* For example: 7d for weekly, 1d for daily
|
|
64
|
+
*/
|
|
65
|
+
readonly interval: TypedTime;
|
|
66
|
+
/**
|
|
67
|
+
* Duration of each repetition
|
|
68
|
+
* For example: 1h for one hour
|
|
69
|
+
*/
|
|
70
|
+
readonly duration: TypedTime;
|
|
71
|
+
/**
|
|
72
|
+
* Offsets from the start time when the session becomes active
|
|
73
|
+
* For example: [0, 3600] for sessions at start time and 1 hour later
|
|
74
|
+
*/
|
|
75
|
+
readonly offsets: readonly TypedTime[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Timezone field (RFC 8866 Section 5.11)
|
|
79
|
+
*
|
|
80
|
+
* Format: z=<adjustment-time> <offset> [<adjustment-time> <offset> ...]
|
|
81
|
+
*
|
|
82
|
+
* Specifies timezone adjustments for repeat sessions.
|
|
83
|
+
* Useful for dealing with daylight saving time changes.
|
|
84
|
+
*/
|
|
85
|
+
export interface Timezone {
|
|
86
|
+
/**
|
|
87
|
+
* List of timezone adjustments
|
|
88
|
+
*/
|
|
89
|
+
readonly adjustments: readonly TimezoneAdjustment[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A single timezone adjustment
|
|
93
|
+
*/
|
|
94
|
+
export interface TimezoneAdjustment {
|
|
95
|
+
/**
|
|
96
|
+
* Time at which the adjustment takes effect (NTP timestamp)
|
|
97
|
+
*/
|
|
98
|
+
readonly time: NtpTime;
|
|
99
|
+
/**
|
|
100
|
+
* Offset to apply at the adjustment time
|
|
101
|
+
* Positive for forward adjustment, negative for backward
|
|
102
|
+
*/
|
|
103
|
+
readonly offset: TypedTime;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create a Timing field
|
|
107
|
+
*/
|
|
108
|
+
export declare function createTiming(startTime: number, stopTime: number): Timing;
|
|
109
|
+
/**
|
|
110
|
+
* Create a permanent/unbounded Timing (0 to 0)
|
|
111
|
+
*/
|
|
112
|
+
export declare function createPermanentTiming(): Timing;
|
|
113
|
+
/**
|
|
114
|
+
* Create a Repeat field
|
|
115
|
+
*/
|
|
116
|
+
export declare function createRepeat(interval: TypedTime, duration: TypedTime, offsets: TypedTime[]): Repeat;
|
|
117
|
+
/**
|
|
118
|
+
* Create a TimezoneAdjustment
|
|
119
|
+
*/
|
|
120
|
+
export declare function createTimezoneAdjustment(time: number, offset: TypedTime): TimezoneAdjustment;
|
|
121
|
+
/**
|
|
122
|
+
* Create a Timezone field
|
|
123
|
+
*/
|
|
124
|
+
export declare function createTimezone(adjustments: TimezoneAdjustment[]): Timezone;
|
|
125
|
+
/**
|
|
126
|
+
* Create a TimeDescription
|
|
127
|
+
*/
|
|
128
|
+
export declare function createTimeDescription(timing: Timing, repeats?: Repeat[], timezone?: Timezone): TimeDescription;
|
|
129
|
+
//# sourceMappingURL=time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/types/time.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,SAAS,EAAkC,MAAM,cAAc,CAAC;AAMlF;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAEpC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,MAAM;IACrB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAMD;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM;IACrB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;CACxC;AAMD;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;CAC5B;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWxE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAK9C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAE,SAAS,EAAE,GACnB,MAAM,CASR;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,kBAAkB,CAK5F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,kBAAkB,EAAE,GAAG,QAAQ,CAO1E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAAM,EAAO,EACtB,QAAQ,CAAC,EAAE,QAAQ,GAClB,eAAe,CAMjB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Time description types for SDP (RFC 8866)
|
|
4
|
+
*
|
|
5
|
+
* Defines types for timing, repeat times, and timezone adjustments.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.createTiming = createTiming;
|
|
9
|
+
exports.createPermanentTiming = createPermanentTiming;
|
|
10
|
+
exports.createRepeat = createRepeat;
|
|
11
|
+
exports.createTimezoneAdjustment = createTimezoneAdjustment;
|
|
12
|
+
exports.createTimezone = createTimezone;
|
|
13
|
+
exports.createTimeDescription = createTimeDescription;
|
|
14
|
+
const primitives_1 = require("./primitives");
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Helper Functions for Creating Time Types
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Create a Timing field
|
|
20
|
+
*/
|
|
21
|
+
function createTiming(startTime, stopTime) {
|
|
22
|
+
if (startTime < 0 || stopTime < 0) {
|
|
23
|
+
throw new Error('NTP times must be non-negative');
|
|
24
|
+
}
|
|
25
|
+
if (startTime !== 0 && stopTime !== 0 && startTime > stopTime) {
|
|
26
|
+
throw new Error('Start time must be before or equal to stop time');
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
startTime: (0, primitives_1.createNtpTime)(startTime),
|
|
30
|
+
stopTime: (0, primitives_1.createNtpTime)(stopTime),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create a permanent/unbounded Timing (0 to 0)
|
|
35
|
+
*/
|
|
36
|
+
function createPermanentTiming() {
|
|
37
|
+
return {
|
|
38
|
+
startTime: (0, primitives_1.createNtpTime)(0),
|
|
39
|
+
stopTime: (0, primitives_1.createNtpTime)(0),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Create a Repeat field
|
|
44
|
+
*/
|
|
45
|
+
function createRepeat(interval, duration, offsets) {
|
|
46
|
+
if (offsets.length === 0) {
|
|
47
|
+
throw new Error('At least one offset is required for repeat');
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
interval,
|
|
51
|
+
duration,
|
|
52
|
+
offsets,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a TimezoneAdjustment
|
|
57
|
+
*/
|
|
58
|
+
function createTimezoneAdjustment(time, offset) {
|
|
59
|
+
return {
|
|
60
|
+
time: (0, primitives_1.createNtpTime)(time),
|
|
61
|
+
offset,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a Timezone field
|
|
66
|
+
*/
|
|
67
|
+
function createTimezone(adjustments) {
|
|
68
|
+
if (adjustments.length === 0) {
|
|
69
|
+
throw new Error('At least one adjustment is required for timezone');
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
adjustments,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create a TimeDescription
|
|
77
|
+
*/
|
|
78
|
+
function createTimeDescription(timing, repeats = [], timezone) {
|
|
79
|
+
return {
|
|
80
|
+
timing,
|
|
81
|
+
repeats,
|
|
82
|
+
timezone,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network address parsing and validation utilities (RFC 8866)
|
|
3
|
+
*
|
|
4
|
+
* Handles IPv4, IPv6 (RFC 5952), and FQDN (RFC 1035) address formats
|
|
5
|
+
*/
|
|
6
|
+
import { IP4Address, IP6Address, FQDN, UnicastAddress } from '../types/network';
|
|
7
|
+
import { AddrType } from '../types/primitives';
|
|
8
|
+
/**
|
|
9
|
+
* Check if a string is a valid IPv4 address
|
|
10
|
+
*
|
|
11
|
+
* Format: a.b.c.d where each octet is 0-255
|
|
12
|
+
*
|
|
13
|
+
* @param input - String to check
|
|
14
|
+
* @returns true if valid IPv4 address
|
|
15
|
+
*/
|
|
16
|
+
export declare function isIP4Address(input: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Check if an IPv4 address is multicast (224.0.0.0 - 239.255.255.255)
|
|
19
|
+
*
|
|
20
|
+
* @param input - IPv4 address string
|
|
21
|
+
* @returns true if multicast address
|
|
22
|
+
*/
|
|
23
|
+
export declare function isIP4MulticastAddress(input: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Parse an IPv4 address string
|
|
26
|
+
*
|
|
27
|
+
* @param input - IPv4 address string
|
|
28
|
+
* @returns IP4Address
|
|
29
|
+
* @throws ParseError if invalid
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseIP4Address(input: string): IP4Address;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a string is a valid IPv6 address (RFC 5952)
|
|
34
|
+
*
|
|
35
|
+
* Supports all IPv6 formats:
|
|
36
|
+
* - Full form: 2001:0db8:0000:0000:0000:0000:0000:0001
|
|
37
|
+
* - Compressed: 2001:db8::1
|
|
38
|
+
* - Mixed IPv4: ::ffff:192.0.2.1
|
|
39
|
+
*
|
|
40
|
+
* @param input - String to check
|
|
41
|
+
* @returns true if valid IPv6 address
|
|
42
|
+
*/
|
|
43
|
+
export declare function isIP6Address(input: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Check if an IPv6 address is multicast (starts with FF)
|
|
46
|
+
*
|
|
47
|
+
* @param input - IPv6 address string
|
|
48
|
+
* @returns true if multicast address
|
|
49
|
+
*/
|
|
50
|
+
export declare function isIP6MulticastAddress(input: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Parse an IPv6 address string
|
|
53
|
+
*
|
|
54
|
+
* @param input - IPv6 address string
|
|
55
|
+
* @returns IP6Address
|
|
56
|
+
* @throws ParseError if invalid
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseIP6Address(input: string): IP6Address;
|
|
59
|
+
/**
|
|
60
|
+
* Check if a string is a valid FQDN (RFC 1035)
|
|
61
|
+
*
|
|
62
|
+
* Rules:
|
|
63
|
+
* - Labels separated by dots
|
|
64
|
+
* - Each label: 1-63 characters
|
|
65
|
+
* - Label format: alphanumeric + hyphens, must start/end with alphanumeric
|
|
66
|
+
* - Total length <= 253 characters
|
|
67
|
+
*
|
|
68
|
+
* @param input - String to check
|
|
69
|
+
* @returns true if valid FQDN
|
|
70
|
+
*/
|
|
71
|
+
export declare function isFQDN(input: string): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Parse an FQDN string
|
|
74
|
+
*
|
|
75
|
+
* @param input - FQDN string
|
|
76
|
+
* @returns FQDN
|
|
77
|
+
* @throws ParseError if invalid
|
|
78
|
+
*/
|
|
79
|
+
export declare function parseFQDN(input: string): FQDN;
|
|
80
|
+
/**
|
|
81
|
+
* Parse a unicast address based on address type
|
|
82
|
+
*
|
|
83
|
+
* For IP4: IPv4 address or FQDN
|
|
84
|
+
* For IP6: IPv6 address or FQDN
|
|
85
|
+
* For other: Extension address
|
|
86
|
+
*
|
|
87
|
+
* @param input - Address string
|
|
88
|
+
* @param addrType - Address type (IP4, IP6, or extension)
|
|
89
|
+
* @returns UnicastAddress
|
|
90
|
+
* @throws ParseError if invalid for the given address type
|
|
91
|
+
*/
|
|
92
|
+
export declare function parseUnicastAddress(input: string, addrType: AddrType): UnicastAddress;
|
|
93
|
+
/**
|
|
94
|
+
* Detect the type of an address string
|
|
95
|
+
*
|
|
96
|
+
* @param input - Address string
|
|
97
|
+
* @returns AddrType ('IP4', 'IP6', or 'extension')
|
|
98
|
+
*/
|
|
99
|
+
export declare function detectAddressType(input: string): AddrType;
|
|
100
|
+
//# sourceMappingURL=address-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address-parser.d.ts","sourceRoot":"","sources":["../../../src/utils/address-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,UAAU,EACV,UAAU,EACV,IAAI,EAEJ,cAAc,EAKf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAO/C;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CA4BnD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAU5D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAKzD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAsFnD;AAeD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAoB5D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAKzD;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CA4B7C;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK7C;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAkCrF;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAgBzD"}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Network address parsing and validation utilities (RFC 8866)
|
|
4
|
+
*
|
|
5
|
+
* Handles IPv4, IPv6 (RFC 5952), and FQDN (RFC 1035) address formats
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.isIP4Address = isIP4Address;
|
|
9
|
+
exports.isIP4MulticastAddress = isIP4MulticastAddress;
|
|
10
|
+
exports.parseIP4Address = parseIP4Address;
|
|
11
|
+
exports.isIP6Address = isIP6Address;
|
|
12
|
+
exports.isIP6MulticastAddress = isIP6MulticastAddress;
|
|
13
|
+
exports.parseIP6Address = parseIP6Address;
|
|
14
|
+
exports.isFQDN = isFQDN;
|
|
15
|
+
exports.parseFQDN = parseFQDN;
|
|
16
|
+
exports.parseUnicastAddress = parseUnicastAddress;
|
|
17
|
+
exports.detectAddressType = detectAddressType;
|
|
18
|
+
const network_1 = require("../types/network");
|
|
19
|
+
const errors_1 = require("../types/errors");
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// IPv4 Address Validation
|
|
22
|
+
// ============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Check if a string is a valid IPv4 address
|
|
25
|
+
*
|
|
26
|
+
* Format: a.b.c.d where each octet is 0-255
|
|
27
|
+
*
|
|
28
|
+
* @param input - String to check
|
|
29
|
+
* @returns true if valid IPv4 address
|
|
30
|
+
*/
|
|
31
|
+
function isIP4Address(input) {
|
|
32
|
+
// Must have exactly 4 octets
|
|
33
|
+
const parts = input.split('.');
|
|
34
|
+
if (parts.length !== 4) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
// Each octet must be 0-255
|
|
38
|
+
return parts.every(part => {
|
|
39
|
+
// Must be numeric
|
|
40
|
+
if (!/^\d+$/.test(part)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const num = parseInt(part, 10);
|
|
44
|
+
// Must be 0-255
|
|
45
|
+
if (num < 0 || num > 255) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
// No leading zeros (except for "0" itself)
|
|
49
|
+
if (part.length > 1 && part[0] === '0') {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if an IPv4 address is multicast (224.0.0.0 - 239.255.255.255)
|
|
57
|
+
*
|
|
58
|
+
* @param input - IPv4 address string
|
|
59
|
+
* @returns true if multicast address
|
|
60
|
+
*/
|
|
61
|
+
function isIP4MulticastAddress(input) {
|
|
62
|
+
if (!isIP4Address(input)) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
const parts = input.split('.');
|
|
66
|
+
const firstOctet = parseInt(parts[0], 10);
|
|
67
|
+
// Multicast range: 224-239
|
|
68
|
+
return firstOctet >= 224 && firstOctet <= 239;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Parse an IPv4 address string
|
|
72
|
+
*
|
|
73
|
+
* @param input - IPv4 address string
|
|
74
|
+
* @returns IP4Address
|
|
75
|
+
* @throws ParseError if invalid
|
|
76
|
+
*/
|
|
77
|
+
function parseIP4Address(input) {
|
|
78
|
+
if (!isIP4Address(input)) {
|
|
79
|
+
throw new errors_1.ParseError(`Invalid IPv4 address: '${input}'`, 0, 0);
|
|
80
|
+
}
|
|
81
|
+
return (0, network_1.createIP4Address)(input);
|
|
82
|
+
}
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// IPv6 Address Validation
|
|
85
|
+
// ============================================================================
|
|
86
|
+
/**
|
|
87
|
+
* Check if a string is a valid IPv6 address (RFC 5952)
|
|
88
|
+
*
|
|
89
|
+
* Supports all IPv6 formats:
|
|
90
|
+
* - Full form: 2001:0db8:0000:0000:0000:0000:0000:0001
|
|
91
|
+
* - Compressed: 2001:db8::1
|
|
92
|
+
* - Mixed IPv4: ::ffff:192.0.2.1
|
|
93
|
+
*
|
|
94
|
+
* @param input - String to check
|
|
95
|
+
* @returns true if valid IPv6 address
|
|
96
|
+
*/
|
|
97
|
+
function isIP6Address(input) {
|
|
98
|
+
// IPv6 address validation regex (comprehensive)
|
|
99
|
+
// Handles all forms including compression and mixed IPv4
|
|
100
|
+
// Special case: "::"
|
|
101
|
+
if (input === '::') {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
// Check for invalid characters
|
|
105
|
+
if (!/^[0-9a-fA-F:.]+$/.test(input)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
// Can have at most one occurrence of "::"
|
|
109
|
+
const doubleColonCount = (input.match(/::/g) || []).length;
|
|
110
|
+
if (doubleColonCount > 1) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
// Split by :: to handle compression
|
|
114
|
+
if (input.includes('::')) {
|
|
115
|
+
const parts = input.split('::');
|
|
116
|
+
if (parts.length !== 2) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
const before = parts[0] ? parts[0].split(':') : [];
|
|
120
|
+
const after = parts[1] ? parts[1].split(':') : [];
|
|
121
|
+
// Check for mixed IPv4 in the last part
|
|
122
|
+
const lastPart = after.length > 0 ? after[after.length - 1] : before[before.length - 1];
|
|
123
|
+
const hasMixedIPv4 = lastPart && lastPart.includes('.');
|
|
124
|
+
if (hasMixedIPv4) {
|
|
125
|
+
// Validate IPv4 part
|
|
126
|
+
if (!isIP4Address(lastPart)) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
// Remove IPv4 part for hex validation
|
|
130
|
+
if (after.length > 0) {
|
|
131
|
+
after.pop();
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
before.pop();
|
|
135
|
+
}
|
|
136
|
+
// IPv4 counts as 2 hex groups
|
|
137
|
+
const totalGroups = before.length + after.length + 2;
|
|
138
|
+
if (totalGroups > 8) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const totalGroups = before.length + after.length;
|
|
144
|
+
if (totalGroups >= 8) {
|
|
145
|
+
return false; // Compression not needed
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Validate hex groups
|
|
149
|
+
return [...before, ...after].every(isValidHexGroup);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// No compression, must have exactly 8 groups (or 6 + IPv4)
|
|
153
|
+
const groups = input.split(':');
|
|
154
|
+
// Check for mixed IPv4 in last group
|
|
155
|
+
const lastGroup = groups[groups.length - 1];
|
|
156
|
+
if (lastGroup && lastGroup.includes('.')) {
|
|
157
|
+
// Mixed form: 6 hex groups + IPv4
|
|
158
|
+
if (groups.length !== 7) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
if (!isIP4Address(lastGroup)) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
// Validate first 6 hex groups
|
|
165
|
+
return groups.slice(0, 6).every(isValidHexGroup);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
// Pure IPv6: must have 8 groups
|
|
169
|
+
if (groups.length !== 8) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
return groups.every(isValidHexGroup);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Check if a string is a valid IPv6 hex group (1-4 hex digits)
|
|
178
|
+
*
|
|
179
|
+
* @param group - Hex group string
|
|
180
|
+
* @returns true if valid
|
|
181
|
+
*/
|
|
182
|
+
function isValidHexGroup(group) {
|
|
183
|
+
if (group.length === 0 || group.length > 4) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
return /^[0-9a-fA-F]+$/.test(group);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Check if an IPv6 address is multicast (starts with FF)
|
|
190
|
+
*
|
|
191
|
+
* @param input - IPv6 address string
|
|
192
|
+
* @returns true if multicast address
|
|
193
|
+
*/
|
|
194
|
+
function isIP6MulticastAddress(input) {
|
|
195
|
+
if (!isIP6Address(input)) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
// Normalize :: compression for checking
|
|
199
|
+
// Multicast addresses start with FF (binary: 11111111)
|
|
200
|
+
const upperInput = input.toUpperCase();
|
|
201
|
+
// Check if first group starts with FF
|
|
202
|
+
if (upperInput.startsWith('FF')) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
// Check after :: compression
|
|
206
|
+
if (upperInput.startsWith('::FF')) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Parse an IPv6 address string
|
|
213
|
+
*
|
|
214
|
+
* @param input - IPv6 address string
|
|
215
|
+
* @returns IP6Address
|
|
216
|
+
* @throws ParseError if invalid
|
|
217
|
+
*/
|
|
218
|
+
function parseIP6Address(input) {
|
|
219
|
+
if (!isIP6Address(input)) {
|
|
220
|
+
throw new errors_1.ParseError(`Invalid IPv6 address: '${input}'`, 0, 0);
|
|
221
|
+
}
|
|
222
|
+
return (0, network_1.createIP6Address)(input);
|
|
223
|
+
}
|
|
224
|
+
// ============================================================================
|
|
225
|
+
// FQDN Validation
|
|
226
|
+
// ============================================================================
|
|
227
|
+
/**
|
|
228
|
+
* Check if a string is a valid FQDN (RFC 1035)
|
|
229
|
+
*
|
|
230
|
+
* Rules:
|
|
231
|
+
* - Labels separated by dots
|
|
232
|
+
* - Each label: 1-63 characters
|
|
233
|
+
* - Label format: alphanumeric + hyphens, must start/end with alphanumeric
|
|
234
|
+
* - Total length <= 253 characters
|
|
235
|
+
*
|
|
236
|
+
* @param input - String to check
|
|
237
|
+
* @returns true if valid FQDN
|
|
238
|
+
*/
|
|
239
|
+
function isFQDN(input) {
|
|
240
|
+
// Total length limit
|
|
241
|
+
if (input.length === 0 || input.length > 253) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
// Split into labels
|
|
245
|
+
const labels = input.split('.');
|
|
246
|
+
// Each label must be valid
|
|
247
|
+
return labels.every(label => {
|
|
248
|
+
// Label length: 1-63 characters
|
|
249
|
+
if (label.length === 0 || label.length > 63) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
// Must start and end with alphanumeric
|
|
253
|
+
if (!/^[a-zA-Z0-9]/.test(label) || !/[a-zA-Z0-9]$/.test(label)) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
// Can only contain alphanumeric and hyphens
|
|
257
|
+
if (!/^[a-zA-Z0-9-]+$/.test(label)) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
return true;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Parse an FQDN string
|
|
265
|
+
*
|
|
266
|
+
* @param input - FQDN string
|
|
267
|
+
* @returns FQDN
|
|
268
|
+
* @throws ParseError if invalid
|
|
269
|
+
*/
|
|
270
|
+
function parseFQDN(input) {
|
|
271
|
+
if (!isFQDN(input)) {
|
|
272
|
+
throw new errors_1.ParseError(`Invalid FQDN: '${input}'`, 0, 0);
|
|
273
|
+
}
|
|
274
|
+
return (0, network_1.createFQDN)(input);
|
|
275
|
+
}
|
|
276
|
+
// ============================================================================
|
|
277
|
+
// Unicast Address Parsing
|
|
278
|
+
// ============================================================================
|
|
279
|
+
/**
|
|
280
|
+
* Parse a unicast address based on address type
|
|
281
|
+
*
|
|
282
|
+
* For IP4: IPv4 address or FQDN
|
|
283
|
+
* For IP6: IPv6 address or FQDN
|
|
284
|
+
* For other: Extension address
|
|
285
|
+
*
|
|
286
|
+
* @param input - Address string
|
|
287
|
+
* @param addrType - Address type (IP4, IP6, or extension)
|
|
288
|
+
* @returns UnicastAddress
|
|
289
|
+
* @throws ParseError if invalid for the given address type
|
|
290
|
+
*/
|
|
291
|
+
function parseUnicastAddress(input, addrType) {
|
|
292
|
+
switch (addrType) {
|
|
293
|
+
case 'IP4':
|
|
294
|
+
// Try IPv4 first, then FQDN
|
|
295
|
+
if (isIP4Address(input)) {
|
|
296
|
+
return (0, network_1.createIP4Address)(input);
|
|
297
|
+
}
|
|
298
|
+
if (isFQDN(input)) {
|
|
299
|
+
return (0, network_1.createFQDN)(input);
|
|
300
|
+
}
|
|
301
|
+
throw new errors_1.ParseError(`Invalid address for type IP4: '${input}' (expected IPv4 or FQDN)`, 0, 0);
|
|
302
|
+
case 'IP6':
|
|
303
|
+
// Try IPv6 first, then FQDN
|
|
304
|
+
if (isIP6Address(input)) {
|
|
305
|
+
return (0, network_1.createIP6Address)(input);
|
|
306
|
+
}
|
|
307
|
+
if (isFQDN(input)) {
|
|
308
|
+
return (0, network_1.createFQDN)(input);
|
|
309
|
+
}
|
|
310
|
+
throw new errors_1.ParseError(`Invalid address for type IP6: '${input}' (expected IPv6 or FQDN)`, 0, 0);
|
|
311
|
+
default:
|
|
312
|
+
// Extension address type
|
|
313
|
+
return (0, network_1.createExtensionAddress)(input);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// ============================================================================
|
|
317
|
+
// Address Type Detection
|
|
318
|
+
// ============================================================================
|
|
319
|
+
/**
|
|
320
|
+
* Detect the type of an address string
|
|
321
|
+
*
|
|
322
|
+
* @param input - Address string
|
|
323
|
+
* @returns AddrType ('IP4', 'IP6', or 'extension')
|
|
324
|
+
*/
|
|
325
|
+
function detectAddressType(input) {
|
|
326
|
+
if (isIP4Address(input)) {
|
|
327
|
+
return 'IP4';
|
|
328
|
+
}
|
|
329
|
+
if (isIP6Address(input)) {
|
|
330
|
+
return 'IP6';
|
|
331
|
+
}
|
|
332
|
+
if (isFQDN(input)) {
|
|
333
|
+
// FQDNs can work with both IP4 and IP6, default to IP4
|
|
334
|
+
return 'IP4';
|
|
335
|
+
}
|
|
336
|
+
// Unknown type
|
|
337
|
+
return 'extension';
|
|
338
|
+
}
|