@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,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Time parsers for SDP (RFC 8866)
|
|
4
|
+
*
|
|
5
|
+
* Parsers for time description fields (t=, r=, z=)
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.parseTimingField = parseTimingField;
|
|
9
|
+
exports.parseRepeatField = parseRepeatField;
|
|
10
|
+
exports.parseTimezoneField = parseTimezoneField;
|
|
11
|
+
exports.parseTimeDescription = parseTimeDescription;
|
|
12
|
+
const primitive_parser_1 = require("./primitive-parser");
|
|
13
|
+
const errors_1 = require("../types/errors");
|
|
14
|
+
const time_1 = require("../types/time");
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Timing Field Parser (t=)
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Parse timing field
|
|
20
|
+
*
|
|
21
|
+
* Format: t=<start-time> <stop-time>
|
|
22
|
+
*
|
|
23
|
+
* Both times are NTP timestamps (seconds since Jan 1, 1900).
|
|
24
|
+
* 0 means unbounded/permanent.
|
|
25
|
+
*
|
|
26
|
+
* @param scanner - Scanner instance
|
|
27
|
+
* @returns Timing object
|
|
28
|
+
* @throws ParseError if invalid format
|
|
29
|
+
*/
|
|
30
|
+
function parseTimingField(scanner) {
|
|
31
|
+
const start = scanner.getPosition();
|
|
32
|
+
// Parse start time
|
|
33
|
+
const startTime = (0, primitive_parser_1.parseNtpTime)(scanner);
|
|
34
|
+
// Expect space
|
|
35
|
+
scanner.expectSpace();
|
|
36
|
+
// Parse stop time
|
|
37
|
+
const stopTime = (0, primitive_parser_1.parseNtpTime)(scanner);
|
|
38
|
+
// Validate timing constraints
|
|
39
|
+
try {
|
|
40
|
+
return (0, time_1.createTiming)(startTime, stopTime);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
throw new errors_1.ParseError(error.message, start.line, start.column);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Repeat Field Parser (r=)
|
|
48
|
+
// ============================================================================
|
|
49
|
+
/**
|
|
50
|
+
* Parse repeat field
|
|
51
|
+
*
|
|
52
|
+
* Format: r=<repeat-interval> <active-duration> <offsets-from-start-time>
|
|
53
|
+
*
|
|
54
|
+
* repeat-interval: Time between repetitions (typed time)
|
|
55
|
+
* active-duration: Duration of each session (typed time)
|
|
56
|
+
* offsets-from-start-time: One or more offsets (typed times)
|
|
57
|
+
*
|
|
58
|
+
* Example: r=7d 1h 0 25h
|
|
59
|
+
* - Repeats weekly (7 days)
|
|
60
|
+
* - Each session is 1 hour
|
|
61
|
+
* - Sessions occur at start time (0) and 25 hours after start
|
|
62
|
+
*
|
|
63
|
+
* @param scanner - Scanner instance
|
|
64
|
+
* @returns Repeat object
|
|
65
|
+
* @throws ParseError if invalid format
|
|
66
|
+
*/
|
|
67
|
+
function parseRepeatField(scanner) {
|
|
68
|
+
const start = scanner.getPosition();
|
|
69
|
+
// Parse repeat interval
|
|
70
|
+
const interval = (0, primitive_parser_1.parseTypedTime)(scanner);
|
|
71
|
+
scanner.expectSpace();
|
|
72
|
+
// Parse active duration
|
|
73
|
+
const duration = (0, primitive_parser_1.parseTypedTime)(scanner);
|
|
74
|
+
// Parse offsets (at least one required)
|
|
75
|
+
const offsets = [];
|
|
76
|
+
while (!scanner.isEOF()) {
|
|
77
|
+
const ch = scanner.peek();
|
|
78
|
+
if (ch === '\r' || ch === '\n') {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
scanner.expectSpace();
|
|
82
|
+
offsets.push((0, primitive_parser_1.parseTypedTime)(scanner));
|
|
83
|
+
}
|
|
84
|
+
// Validate at least one offset
|
|
85
|
+
if (offsets.length === 0) {
|
|
86
|
+
throw new errors_1.ParseError('Repeat field requires at least one offset', start.line, start.column);
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
return (0, time_1.createRepeat)(interval, duration, offsets);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
throw new errors_1.ParseError(error.message, start.line, start.column);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// Timezone Field Parser (z=)
|
|
97
|
+
// ============================================================================
|
|
98
|
+
/**
|
|
99
|
+
* Parse timezone field
|
|
100
|
+
*
|
|
101
|
+
* Format: z=<adjustment-time> <offset> [<adjustment-time> <offset> ...]
|
|
102
|
+
*
|
|
103
|
+
* adjustment-time: NTP timestamp when adjustment takes effect
|
|
104
|
+
* offset: Typed time offset to apply
|
|
105
|
+
*
|
|
106
|
+
* Example: z=2882844526 -1h 2898848070 0
|
|
107
|
+
* - At time 2882844526, apply -1h offset (fall back)
|
|
108
|
+
* - At time 2898848070, apply 0 offset (return to standard)
|
|
109
|
+
*
|
|
110
|
+
* @param scanner - Scanner instance
|
|
111
|
+
* @returns Timezone object
|
|
112
|
+
* @throws ParseError if invalid format
|
|
113
|
+
*/
|
|
114
|
+
function parseTimezoneField(scanner) {
|
|
115
|
+
const start = scanner.getPosition();
|
|
116
|
+
const adjustments = [];
|
|
117
|
+
while (!scanner.isEOF()) {
|
|
118
|
+
const ch = scanner.peek();
|
|
119
|
+
if (ch === '\r' || ch === '\n') {
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
// Parse adjustment time
|
|
123
|
+
const time = (0, primitive_parser_1.parseNtpTime)(scanner);
|
|
124
|
+
scanner.expectSpace();
|
|
125
|
+
// Parse offset (can be negative, but parseTypedTime handles the sign in the string)
|
|
126
|
+
const offset = (0, primitive_parser_1.parseTypedTime)(scanner);
|
|
127
|
+
adjustments.push((0, time_1.createTimezoneAdjustment)(time, offset));
|
|
128
|
+
// Check for more adjustments
|
|
129
|
+
if (!scanner.isEOF()) {
|
|
130
|
+
const nextCh = scanner.peek();
|
|
131
|
+
if (nextCh !== '\r' && nextCh !== '\n') {
|
|
132
|
+
scanner.expectSpace();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Validate at least one adjustment
|
|
137
|
+
if (adjustments.length === 0) {
|
|
138
|
+
throw new errors_1.ParseError('Timezone field requires at least one adjustment', start.line, start.column);
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
return (0, time_1.createTimezone)(adjustments);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
throw new errors_1.ParseError(error.message, start.line, start.column);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// ============================================================================
|
|
148
|
+
// Time Description Parser (combination of t=, r=, z=)
|
|
149
|
+
// ============================================================================
|
|
150
|
+
/**
|
|
151
|
+
* Parse a time description
|
|
152
|
+
*
|
|
153
|
+
* A time description consists of:
|
|
154
|
+
* - One timing field (t=) [required]
|
|
155
|
+
* - Zero or more repeat fields (r=) [optional]
|
|
156
|
+
* - Zero or one timezone field (z=) [optional]
|
|
157
|
+
*
|
|
158
|
+
* This is typically used when parsing the time section of an SDP,
|
|
159
|
+
* but the individual field parsers above can be used for line-by-line parsing.
|
|
160
|
+
*
|
|
161
|
+
* @param timing - Timing field
|
|
162
|
+
* @param repeats - Repeat fields (optional)
|
|
163
|
+
* @param timezone - Timezone field (optional)
|
|
164
|
+
* @returns TimeDescription object
|
|
165
|
+
*/
|
|
166
|
+
function parseTimeDescription(timing, repeats = [], timezone) {
|
|
167
|
+
return (0, time_1.createTimeDescription)(timing, repeats, timezone);
|
|
168
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribute serializers for SDP (RFC 8866)
|
|
3
|
+
*
|
|
4
|
+
* Serializers for SDP attributes (a= fields).
|
|
5
|
+
*/
|
|
6
|
+
import { Attribute } from '../types/attributes';
|
|
7
|
+
/**
|
|
8
|
+
* Serialize attribute field
|
|
9
|
+
*
|
|
10
|
+
* Formats:
|
|
11
|
+
* - Property attribute: a=<attribute-name>
|
|
12
|
+
* - Value attribute: a=<attribute-name>:<attribute-value>
|
|
13
|
+
*
|
|
14
|
+
* @param attr - Attribute object
|
|
15
|
+
* @returns Serialized attribute line (without line ending)
|
|
16
|
+
*/
|
|
17
|
+
export declare function serializeAttributeField(attr: Attribute): string;
|
|
18
|
+
//# sourceMappingURL=attribute-serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-serializer.d.ts","sourceRoot":"","sources":["../../../src/serializer/attribute-serializer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAyC,MAAM,qBAAqB,CAAC;AAMvF;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAY/D"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Attribute serializers for SDP (RFC 8866)
|
|
4
|
+
*
|
|
5
|
+
* Serializers for SDP attributes (a= fields).
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.serializeAttributeField = serializeAttributeField;
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Attribute Field Serializer (a=)
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Serialize attribute field
|
|
14
|
+
*
|
|
15
|
+
* Formats:
|
|
16
|
+
* - Property attribute: a=<attribute-name>
|
|
17
|
+
* - Value attribute: a=<attribute-name>:<attribute-value>
|
|
18
|
+
*
|
|
19
|
+
* @param attr - Attribute object
|
|
20
|
+
* @returns Serialized attribute line (without line ending)
|
|
21
|
+
*/
|
|
22
|
+
function serializeAttributeField(attr) {
|
|
23
|
+
switch (attr.kind) {
|
|
24
|
+
case 'property':
|
|
25
|
+
return `a=${attr.name}`;
|
|
26
|
+
case 'value':
|
|
27
|
+
return `a=${attr.name}:${attr.value}`;
|
|
28
|
+
default: {
|
|
29
|
+
// Exhaustive check - ensures all cases are handled
|
|
30
|
+
const _exhaustive = attr;
|
|
31
|
+
return _exhaustive;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field serializers for SDP (RFC 8866)
|
|
3
|
+
*
|
|
4
|
+
* Serializers for individual SDP field types to convert them back to SDP text format.
|
|
5
|
+
*/
|
|
6
|
+
import { Version, SessionName, Information, URI, Email, Phone, Key } from '../types/primitives';
|
|
7
|
+
import { Origin, Connection, Bandwidth } from '../types/fields';
|
|
8
|
+
import { ConnectionAddress } from '../types/network';
|
|
9
|
+
/**
|
|
10
|
+
* Serialize version field
|
|
11
|
+
*
|
|
12
|
+
* Format: v=0
|
|
13
|
+
*
|
|
14
|
+
* @param version - Version number
|
|
15
|
+
* @returns Serialized version line (without line ending)
|
|
16
|
+
*/
|
|
17
|
+
export declare function serializeVersionField(version: Version): string;
|
|
18
|
+
/**
|
|
19
|
+
* Serialize origin field
|
|
20
|
+
*
|
|
21
|
+
* Format: o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
|
|
22
|
+
*
|
|
23
|
+
* @param origin - Origin object
|
|
24
|
+
* @returns Serialized origin line (without line ending)
|
|
25
|
+
*/
|
|
26
|
+
export declare function serializeOriginField(origin: Origin): string;
|
|
27
|
+
/**
|
|
28
|
+
* Serialize session name field
|
|
29
|
+
*
|
|
30
|
+
* Format: s=<session name>
|
|
31
|
+
*
|
|
32
|
+
* @param sessionName - Session name
|
|
33
|
+
* @returns Serialized session name line (without line ending)
|
|
34
|
+
*/
|
|
35
|
+
export declare function serializeSessionNameField(sessionName: SessionName): string;
|
|
36
|
+
/**
|
|
37
|
+
* Serialize information field
|
|
38
|
+
*
|
|
39
|
+
* Format: i=<session information>
|
|
40
|
+
*
|
|
41
|
+
* @param information - Information string
|
|
42
|
+
* @returns Serialized information line (without line ending)
|
|
43
|
+
*/
|
|
44
|
+
export declare function serializeInformationField(information: Information): string;
|
|
45
|
+
/**
|
|
46
|
+
* Serialize URI field
|
|
47
|
+
*
|
|
48
|
+
* Format: u=<uri>
|
|
49
|
+
*
|
|
50
|
+
* @param uri - URI string
|
|
51
|
+
* @returns Serialized URI line (without line ending)
|
|
52
|
+
*/
|
|
53
|
+
export declare function serializeUriField(uri: URI): string;
|
|
54
|
+
/**
|
|
55
|
+
* Serialize email field
|
|
56
|
+
*
|
|
57
|
+
* Format: e=<email-address>
|
|
58
|
+
*
|
|
59
|
+
* @param email - Email string
|
|
60
|
+
* @returns Serialized email line (without line ending)
|
|
61
|
+
*/
|
|
62
|
+
export declare function serializeEmailField(email: Email): string;
|
|
63
|
+
/**
|
|
64
|
+
* Serialize phone field
|
|
65
|
+
*
|
|
66
|
+
* Format: p=<phone-number>
|
|
67
|
+
*
|
|
68
|
+
* @param phone - Phone string
|
|
69
|
+
* @returns Serialized phone line (without line ending)
|
|
70
|
+
*/
|
|
71
|
+
export declare function serializePhoneField(phone: Phone): string;
|
|
72
|
+
/**
|
|
73
|
+
* Serialize connection field
|
|
74
|
+
*
|
|
75
|
+
* Format: c=<nettype> <addrtype> <connection-address>
|
|
76
|
+
*
|
|
77
|
+
* Connection address formats:
|
|
78
|
+
* - Unicast: <address>
|
|
79
|
+
* - IPv4 multicast: <address>/<ttl>[/<numAddresses>]
|
|
80
|
+
* - IPv6 multicast: <address>[/<numAddresses>]
|
|
81
|
+
* - FQDN multicast: <address>[/<ttl>][/<numAddresses>]
|
|
82
|
+
*
|
|
83
|
+
* @param connection - Connection object
|
|
84
|
+
* @returns Serialized connection line (without line ending)
|
|
85
|
+
*/
|
|
86
|
+
export declare function serializeConnectionField(connection: Connection): string;
|
|
87
|
+
/**
|
|
88
|
+
* Serialize connection address (unicast or multicast)
|
|
89
|
+
*
|
|
90
|
+
* @param address - Connection address
|
|
91
|
+
* @returns Serialized address string
|
|
92
|
+
*/
|
|
93
|
+
export declare function serializeConnectionAddress(address: ConnectionAddress): string;
|
|
94
|
+
/**
|
|
95
|
+
* Serialize bandwidth field
|
|
96
|
+
*
|
|
97
|
+
* Format: b=<bwtype>:<bandwidth>
|
|
98
|
+
*
|
|
99
|
+
* @param bandwidth - Bandwidth object
|
|
100
|
+
* @returns Serialized bandwidth line (without line ending)
|
|
101
|
+
*/
|
|
102
|
+
export declare function serializeBandwidthField(bandwidth: Bandwidth): string;
|
|
103
|
+
/**
|
|
104
|
+
* Serialize key field (OBSOLETE per RFC 8866)
|
|
105
|
+
*
|
|
106
|
+
* Format: k=<method>:<key> or k=<method>
|
|
107
|
+
*
|
|
108
|
+
* @param key - Key string
|
|
109
|
+
* @returns Serialized key line (without line ending)
|
|
110
|
+
*/
|
|
111
|
+
export declare function serializeKeyField(key: Key): string;
|
|
112
|
+
//# sourceMappingURL=field-serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-serializer.d.ts","sourceRoot":"","sources":["../../../src/serializer/field-serializer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACX,GAAG,EACH,KAAK,EACL,KAAK,EACL,GAAG,EACJ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EACL,iBAAiB,EAKlB,MAAM,kBAAkB,CAAC;AAM1B;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAE9D;AAMD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAMD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAE1E;AAMD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAE1E;AAMD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAElD;AAMD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAExD;AAMD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAExD;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAGvE;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CA0C7E;AAMD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAEpE;AAMD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAElD"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Field serializers for SDP (RFC 8866)
|
|
4
|
+
*
|
|
5
|
+
* Serializers for individual SDP field types to convert them back to SDP text format.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.serializeVersionField = serializeVersionField;
|
|
9
|
+
exports.serializeOriginField = serializeOriginField;
|
|
10
|
+
exports.serializeSessionNameField = serializeSessionNameField;
|
|
11
|
+
exports.serializeInformationField = serializeInformationField;
|
|
12
|
+
exports.serializeUriField = serializeUriField;
|
|
13
|
+
exports.serializeEmailField = serializeEmailField;
|
|
14
|
+
exports.serializePhoneField = serializePhoneField;
|
|
15
|
+
exports.serializeConnectionField = serializeConnectionField;
|
|
16
|
+
exports.serializeConnectionAddress = serializeConnectionAddress;
|
|
17
|
+
exports.serializeBandwidthField = serializeBandwidthField;
|
|
18
|
+
exports.serializeKeyField = serializeKeyField;
|
|
19
|
+
const network_1 = require("../types/network");
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Version Field Serializer (v=)
|
|
22
|
+
// ============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Serialize version field
|
|
25
|
+
*
|
|
26
|
+
* Format: v=0
|
|
27
|
+
*
|
|
28
|
+
* @param version - Version number
|
|
29
|
+
* @returns Serialized version line (without line ending)
|
|
30
|
+
*/
|
|
31
|
+
function serializeVersionField(version) {
|
|
32
|
+
return `v=${version}`;
|
|
33
|
+
}
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Origin Field Serializer (o=)
|
|
36
|
+
// ============================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Serialize origin field
|
|
39
|
+
*
|
|
40
|
+
* Format: o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
|
|
41
|
+
*
|
|
42
|
+
* @param origin - Origin object
|
|
43
|
+
* @returns Serialized origin line (without line ending)
|
|
44
|
+
*/
|
|
45
|
+
function serializeOriginField(origin) {
|
|
46
|
+
return `o=${origin.username} ${origin.sessId} ${origin.sessVersion} ${origin.netType} ${origin.addrType} ${origin.unicastAddress}`;
|
|
47
|
+
}
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Session Name Field Serializer (s=)
|
|
50
|
+
// ============================================================================
|
|
51
|
+
/**
|
|
52
|
+
* Serialize session name field
|
|
53
|
+
*
|
|
54
|
+
* Format: s=<session name>
|
|
55
|
+
*
|
|
56
|
+
* @param sessionName - Session name
|
|
57
|
+
* @returns Serialized session name line (without line ending)
|
|
58
|
+
*/
|
|
59
|
+
function serializeSessionNameField(sessionName) {
|
|
60
|
+
return `s=${sessionName}`;
|
|
61
|
+
}
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// Information Field Serializer (i=)
|
|
64
|
+
// ============================================================================
|
|
65
|
+
/**
|
|
66
|
+
* Serialize information field
|
|
67
|
+
*
|
|
68
|
+
* Format: i=<session information>
|
|
69
|
+
*
|
|
70
|
+
* @param information - Information string
|
|
71
|
+
* @returns Serialized information line (without line ending)
|
|
72
|
+
*/
|
|
73
|
+
function serializeInformationField(information) {
|
|
74
|
+
return `i=${information}`;
|
|
75
|
+
}
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// URI Field Serializer (u=)
|
|
78
|
+
// ============================================================================
|
|
79
|
+
/**
|
|
80
|
+
* Serialize URI field
|
|
81
|
+
*
|
|
82
|
+
* Format: u=<uri>
|
|
83
|
+
*
|
|
84
|
+
* @param uri - URI string
|
|
85
|
+
* @returns Serialized URI line (without line ending)
|
|
86
|
+
*/
|
|
87
|
+
function serializeUriField(uri) {
|
|
88
|
+
return `u=${uri}`;
|
|
89
|
+
}
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// Email Field Serializer (e=)
|
|
92
|
+
// ============================================================================
|
|
93
|
+
/**
|
|
94
|
+
* Serialize email field
|
|
95
|
+
*
|
|
96
|
+
* Format: e=<email-address>
|
|
97
|
+
*
|
|
98
|
+
* @param email - Email string
|
|
99
|
+
* @returns Serialized email line (without line ending)
|
|
100
|
+
*/
|
|
101
|
+
function serializeEmailField(email) {
|
|
102
|
+
return `e=${email}`;
|
|
103
|
+
}
|
|
104
|
+
// ============================================================================
|
|
105
|
+
// Phone Field Serializer (p=)
|
|
106
|
+
// ============================================================================
|
|
107
|
+
/**
|
|
108
|
+
* Serialize phone field
|
|
109
|
+
*
|
|
110
|
+
* Format: p=<phone-number>
|
|
111
|
+
*
|
|
112
|
+
* @param phone - Phone string
|
|
113
|
+
* @returns Serialized phone line (without line ending)
|
|
114
|
+
*/
|
|
115
|
+
function serializePhoneField(phone) {
|
|
116
|
+
return `p=${phone}`;
|
|
117
|
+
}
|
|
118
|
+
// ============================================================================
|
|
119
|
+
// Connection Field Serializer (c=)
|
|
120
|
+
// ============================================================================
|
|
121
|
+
/**
|
|
122
|
+
* Serialize connection field
|
|
123
|
+
*
|
|
124
|
+
* Format: c=<nettype> <addrtype> <connection-address>
|
|
125
|
+
*
|
|
126
|
+
* Connection address formats:
|
|
127
|
+
* - Unicast: <address>
|
|
128
|
+
* - IPv4 multicast: <address>/<ttl>[/<numAddresses>]
|
|
129
|
+
* - IPv6 multicast: <address>[/<numAddresses>]
|
|
130
|
+
* - FQDN multicast: <address>[/<ttl>][/<numAddresses>]
|
|
131
|
+
*
|
|
132
|
+
* @param connection - Connection object
|
|
133
|
+
* @returns Serialized connection line (without line ending)
|
|
134
|
+
*/
|
|
135
|
+
function serializeConnectionField(connection) {
|
|
136
|
+
const addressStr = serializeConnectionAddress(connection.connectionAddress);
|
|
137
|
+
return `c=${connection.netType} ${connection.addrType} ${addressStr}`;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Serialize connection address (unicast or multicast)
|
|
141
|
+
*
|
|
142
|
+
* @param address - Connection address
|
|
143
|
+
* @returns Serialized address string
|
|
144
|
+
*/
|
|
145
|
+
function serializeConnectionAddress(address) {
|
|
146
|
+
if (!(0, network_1.isMulticastAddress)(address)) {
|
|
147
|
+
// Unicast address - just the address string
|
|
148
|
+
return address;
|
|
149
|
+
}
|
|
150
|
+
// Multicast address
|
|
151
|
+
if ((0, network_1.isIP4MulticastAddress)(address)) {
|
|
152
|
+
// IPv4 multicast: <address>/<ttl>[/<numAddresses>]
|
|
153
|
+
let result = `${address.address}/${address.ttl}`;
|
|
154
|
+
if (address.numAddresses !== undefined) {
|
|
155
|
+
result += `/${address.numAddresses}`;
|
|
156
|
+
}
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
if ((0, network_1.isIP6MulticastAddress)(address)) {
|
|
160
|
+
// IPv6 multicast: <address>[/<numAddresses>]
|
|
161
|
+
if (address.numAddresses !== undefined) {
|
|
162
|
+
return `${address.address}/${address.numAddresses}`;
|
|
163
|
+
}
|
|
164
|
+
return address.address;
|
|
165
|
+
}
|
|
166
|
+
if ((0, network_1.isFQDNMulticastAddress)(address)) {
|
|
167
|
+
// FQDN multicast: <address>[/<ttl>][/<numAddresses>]
|
|
168
|
+
let result = address.address;
|
|
169
|
+
if (address.ttl !== undefined) {
|
|
170
|
+
result += `/${address.ttl}`;
|
|
171
|
+
if (address.numAddresses !== undefined) {
|
|
172
|
+
result += `/${address.numAddresses}`;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else if (address.numAddresses !== undefined) {
|
|
176
|
+
// numAddresses without TTL - this is unusual but handle it
|
|
177
|
+
result += `/${address.numAddresses}`;
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
// Exhaustive check - this should never be reached
|
|
182
|
+
const _exhaustive = address;
|
|
183
|
+
return _exhaustive;
|
|
184
|
+
}
|
|
185
|
+
// ============================================================================
|
|
186
|
+
// Bandwidth Field Serializer (b=)
|
|
187
|
+
// ============================================================================
|
|
188
|
+
/**
|
|
189
|
+
* Serialize bandwidth field
|
|
190
|
+
*
|
|
191
|
+
* Format: b=<bwtype>:<bandwidth>
|
|
192
|
+
*
|
|
193
|
+
* @param bandwidth - Bandwidth object
|
|
194
|
+
* @returns Serialized bandwidth line (without line ending)
|
|
195
|
+
*/
|
|
196
|
+
function serializeBandwidthField(bandwidth) {
|
|
197
|
+
return `b=${bandwidth.type}:${bandwidth.value}`;
|
|
198
|
+
}
|
|
199
|
+
// ============================================================================
|
|
200
|
+
// Key Field Serializer (k=)
|
|
201
|
+
// ============================================================================
|
|
202
|
+
/**
|
|
203
|
+
* Serialize key field (OBSOLETE per RFC 8866)
|
|
204
|
+
*
|
|
205
|
+
* Format: k=<method>:<key> or k=<method>
|
|
206
|
+
*
|
|
207
|
+
* @param key - Key string
|
|
208
|
+
* @returns Serialized key line (without line ending)
|
|
209
|
+
*/
|
|
210
|
+
function serializeKeyField(key) {
|
|
211
|
+
return `k=${key}`;
|
|
212
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media serializers for SDP (RFC 8866)
|
|
3
|
+
*
|
|
4
|
+
* Serializers for media descriptions (m= and associated fields).
|
|
5
|
+
*/
|
|
6
|
+
import { Media, MediaDescription } from '../types/media';
|
|
7
|
+
/**
|
|
8
|
+
* Serialize media field
|
|
9
|
+
*
|
|
10
|
+
* Format: m=<media> <port>[/<number of ports>] <proto> <fmt> [<fmt> ...]
|
|
11
|
+
*
|
|
12
|
+
* @param media - Media object
|
|
13
|
+
* @returns Serialized media line (without line ending)
|
|
14
|
+
*/
|
|
15
|
+
export declare function serializeMediaField(media: Media): string;
|
|
16
|
+
/**
|
|
17
|
+
* Serialize a complete media description
|
|
18
|
+
*
|
|
19
|
+
* Outputs:
|
|
20
|
+
* - One m= line
|
|
21
|
+
* - Zero or one i= line
|
|
22
|
+
* - Zero or more c= lines
|
|
23
|
+
* - Zero or more b= lines
|
|
24
|
+
* - Zero or one k= line
|
|
25
|
+
* - Zero or more a= lines
|
|
26
|
+
*
|
|
27
|
+
* @param md - MediaDescription object
|
|
28
|
+
* @returns Array of serialized lines (without line endings)
|
|
29
|
+
*/
|
|
30
|
+
export declare function serializeMediaDescription(md: MediaDescription): string[];
|
|
31
|
+
//# sourceMappingURL=media-serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-serializer.d.ts","sourceRoot":"","sources":["../../../src/serializer/media-serializer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAA6B,MAAM,gBAAgB,CAAC;AAapF;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAgBxD;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAgCxE"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Media serializers for SDP (RFC 8866)
|
|
4
|
+
*
|
|
5
|
+
* Serializers for media descriptions (m= and associated fields).
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.serializeMediaField = serializeMediaField;
|
|
9
|
+
exports.serializeMediaDescription = serializeMediaDescription;
|
|
10
|
+
const media_1 = require("../types/media");
|
|
11
|
+
const field_serializer_1 = require("./field-serializer");
|
|
12
|
+
const attribute_serializer_1 = require("./attribute-serializer");
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Media Field Serializer (m=)
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Serialize media field
|
|
18
|
+
*
|
|
19
|
+
* Format: m=<media> <port>[/<number of ports>] <proto> <fmt> [<fmt> ...]
|
|
20
|
+
*
|
|
21
|
+
* @param media - Media object
|
|
22
|
+
* @returns Serialized media line (without line ending)
|
|
23
|
+
*/
|
|
24
|
+
function serializeMediaField(media) {
|
|
25
|
+
// Serialize port
|
|
26
|
+
let portStr;
|
|
27
|
+
if ((0, media_1.isSimplePort)(media.port)) {
|
|
28
|
+
portStr = media.port.value.toString();
|
|
29
|
+
}
|
|
30
|
+
else if ((0, media_1.isPortRange)(media.port)) {
|
|
31
|
+
portStr = `${media.port.base}/${media.port.count}`;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Should not happen, but handle gracefully
|
|
35
|
+
portStr = '0';
|
|
36
|
+
}
|
|
37
|
+
// Serialize formats
|
|
38
|
+
const formatsStr = media.formats.join(' ');
|
|
39
|
+
return `m=${media.type} ${portStr} ${media.proto} ${formatsStr}`;
|
|
40
|
+
}
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// Media Description Serializer
|
|
43
|
+
// ============================================================================
|
|
44
|
+
/**
|
|
45
|
+
* Serialize a complete media description
|
|
46
|
+
*
|
|
47
|
+
* Outputs:
|
|
48
|
+
* - One m= line
|
|
49
|
+
* - Zero or one i= line
|
|
50
|
+
* - Zero or more c= lines
|
|
51
|
+
* - Zero or more b= lines
|
|
52
|
+
* - Zero or one k= line
|
|
53
|
+
* - Zero or more a= lines
|
|
54
|
+
*
|
|
55
|
+
* @param md - MediaDescription object
|
|
56
|
+
* @returns Array of serialized lines (without line endings)
|
|
57
|
+
*/
|
|
58
|
+
function serializeMediaDescription(md) {
|
|
59
|
+
const lines = [];
|
|
60
|
+
// m= media (required)
|
|
61
|
+
lines.push(serializeMediaField(md.media));
|
|
62
|
+
// i= information (optional)
|
|
63
|
+
if (md.information !== undefined) {
|
|
64
|
+
lines.push((0, field_serializer_1.serializeInformationField)(md.information));
|
|
65
|
+
}
|
|
66
|
+
// c= connections (optional, multiple)
|
|
67
|
+
for (const connection of md.connections) {
|
|
68
|
+
lines.push((0, field_serializer_1.serializeConnectionField)(connection));
|
|
69
|
+
}
|
|
70
|
+
// b= bandwidths (optional, multiple)
|
|
71
|
+
for (const bandwidth of md.bandwidths) {
|
|
72
|
+
lines.push((0, field_serializer_1.serializeBandwidthField)(bandwidth));
|
|
73
|
+
}
|
|
74
|
+
// k= key (optional, OBSOLETE)
|
|
75
|
+
if (md.key !== undefined) {
|
|
76
|
+
lines.push((0, field_serializer_1.serializeKeyField)(md.key));
|
|
77
|
+
}
|
|
78
|
+
// a= attributes (optional, multiple)
|
|
79
|
+
for (const attr of md.attributes) {
|
|
80
|
+
lines.push((0, attribute_serializer_1.serializeAttributeField)(attr));
|
|
81
|
+
}
|
|
82
|
+
return lines;
|
|
83
|
+
}
|