@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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/dist/src/builder/media-builder.d.ts +221 -0
  4. package/dist/src/builder/media-builder.d.ts.map +1 -0
  5. package/dist/src/builder/media-builder.js +385 -0
  6. package/dist/src/builder/session-builder.d.ts +195 -0
  7. package/dist/src/builder/session-builder.d.ts.map +1 -0
  8. package/dist/src/builder/session-builder.js +366 -0
  9. package/dist/src/index.d.ts +67 -0
  10. package/dist/src/index.d.ts.map +1 -0
  11. package/dist/src/index.js +250 -0
  12. package/dist/src/parser/attribute-parser.d.ts +100 -0
  13. package/dist/src/parser/attribute-parser.d.ts.map +1 -0
  14. package/dist/src/parser/attribute-parser.js +217 -0
  15. package/dist/src/parser/field-parser.d.ts +124 -0
  16. package/dist/src/parser/field-parser.d.ts.map +1 -0
  17. package/dist/src/parser/field-parser.js +335 -0
  18. package/dist/src/parser/media-parser.d.ts +45 -0
  19. package/dist/src/parser/media-parser.d.ts.map +1 -0
  20. package/dist/src/parser/media-parser.js +157 -0
  21. package/dist/src/parser/primitive-parser.d.ts +138 -0
  22. package/dist/src/parser/primitive-parser.d.ts.map +1 -0
  23. package/dist/src/parser/primitive-parser.js +316 -0
  24. package/dist/src/parser/scanner.d.ts +142 -0
  25. package/dist/src/parser/scanner.d.ts.map +1 -0
  26. package/dist/src/parser/scanner.js +284 -0
  27. package/dist/src/parser/session-parser.d.ts +35 -0
  28. package/dist/src/parser/session-parser.d.ts.map +1 -0
  29. package/dist/src/parser/session-parser.js +207 -0
  30. package/dist/src/parser/time-parser.d.ts +74 -0
  31. package/dist/src/parser/time-parser.d.ts.map +1 -0
  32. package/dist/src/parser/time-parser.js +168 -0
  33. package/dist/src/serializer/attribute-serializer.d.ts +18 -0
  34. package/dist/src/serializer/attribute-serializer.d.ts.map +1 -0
  35. package/dist/src/serializer/attribute-serializer.js +34 -0
  36. package/dist/src/serializer/field-serializer.d.ts +112 -0
  37. package/dist/src/serializer/field-serializer.d.ts.map +1 -0
  38. package/dist/src/serializer/field-serializer.js +212 -0
  39. package/dist/src/serializer/media-serializer.d.ts +31 -0
  40. package/dist/src/serializer/media-serializer.d.ts.map +1 -0
  41. package/dist/src/serializer/media-serializer.js +83 -0
  42. package/dist/src/serializer/session-serializer.d.ts +29 -0
  43. package/dist/src/serializer/session-serializer.d.ts.map +1 -0
  44. package/dist/src/serializer/session-serializer.js +99 -0
  45. package/dist/src/serializer/time-serializer.d.ts +46 -0
  46. package/dist/src/serializer/time-serializer.d.ts.map +1 -0
  47. package/dist/src/serializer/time-serializer.js +86 -0
  48. package/dist/src/types/attributes.d.ts +318 -0
  49. package/dist/src/types/attributes.d.ts.map +1 -0
  50. package/dist/src/types/attributes.js +225 -0
  51. package/dist/src/types/errors.d.ts +129 -0
  52. package/dist/src/types/errors.d.ts.map +1 -0
  53. package/dist/src/types/errors.js +186 -0
  54. package/dist/src/types/fields.d.ts +100 -0
  55. package/dist/src/types/fields.d.ts.map +1 -0
  56. package/dist/src/types/fields.js +48 -0
  57. package/dist/src/types/media.d.ts +148 -0
  58. package/dist/src/types/media.d.ts.map +1 -0
  59. package/dist/src/types/media.js +137 -0
  60. package/dist/src/types/network.d.ts +136 -0
  61. package/dist/src/types/network.d.ts.map +1 -0
  62. package/dist/src/types/network.js +130 -0
  63. package/dist/src/types/primitives.d.ts +193 -0
  64. package/dist/src/types/primitives.d.ts.map +1 -0
  65. package/dist/src/types/primitives.js +195 -0
  66. package/dist/src/types/session.d.ts +122 -0
  67. package/dist/src/types/session.d.ts.map +1 -0
  68. package/dist/src/types/session.js +81 -0
  69. package/dist/src/types/time.d.ts +129 -0
  70. package/dist/src/types/time.d.ts.map +1 -0
  71. package/dist/src/types/time.js +84 -0
  72. package/dist/src/utils/address-parser.d.ts +100 -0
  73. package/dist/src/utils/address-parser.d.ts.map +1 -0
  74. package/dist/src/utils/address-parser.js +338 -0
  75. package/dist/src/utils/format-validators.d.ts +77 -0
  76. package/dist/src/utils/format-validators.d.ts.map +1 -0
  77. package/dist/src/utils/format-validators.js +504 -0
  78. package/dist/src/utils/line-reader.d.ts +84 -0
  79. package/dist/src/utils/line-reader.d.ts.map +1 -0
  80. package/dist/src/utils/line-reader.js +169 -0
  81. package/dist/src/utils/time-converter.d.ts +99 -0
  82. package/dist/src/utils/time-converter.d.ts.map +1 -0
  83. package/dist/src/utils/time-converter.js +195 -0
  84. package/dist/src/validator/media-validator.d.ts +27 -0
  85. package/dist/src/validator/media-validator.d.ts.map +1 -0
  86. package/dist/src/validator/media-validator.js +241 -0
  87. package/dist/src/validator/semantic-validator.d.ts +47 -0
  88. package/dist/src/validator/semantic-validator.d.ts.map +1 -0
  89. package/dist/src/validator/semantic-validator.js +207 -0
  90. package/dist/src/validator/session-validator.d.ts +36 -0
  91. package/dist/src/validator/session-validator.d.ts.map +1 -0
  92. package/dist/src/validator/session-validator.js +280 -0
  93. package/dist/tests/integration/round-trip.test.d.ts +5 -0
  94. package/dist/tests/integration/round-trip.test.d.ts.map +1 -0
  95. package/dist/tests/integration/round-trip.test.js +320 -0
  96. package/dist/tests/integration/voip-examples.test.d.ts +5 -0
  97. package/dist/tests/integration/voip-examples.test.d.ts.map +1 -0
  98. package/dist/tests/integration/voip-examples.test.js +361 -0
  99. package/dist/tests/unit/builder/media-builder.test.d.ts +5 -0
  100. package/dist/tests/unit/builder/media-builder.test.d.ts.map +1 -0
  101. package/dist/tests/unit/builder/media-builder.test.js +524 -0
  102. package/dist/tests/unit/builder/session-builder.test.d.ts +5 -0
  103. package/dist/tests/unit/builder/session-builder.test.d.ts.map +1 -0
  104. package/dist/tests/unit/builder/session-builder.test.js +367 -0
  105. package/dist/tests/unit/parser/attribute-parser.test.d.ts +5 -0
  106. package/dist/tests/unit/parser/attribute-parser.test.d.ts.map +1 -0
  107. package/dist/tests/unit/parser/attribute-parser.test.js +319 -0
  108. package/dist/tests/unit/parser/field-parser.test.d.ts +5 -0
  109. package/dist/tests/unit/parser/field-parser.test.d.ts.map +1 -0
  110. package/dist/tests/unit/parser/field-parser.test.js +355 -0
  111. package/dist/tests/unit/parser/media-parser.test.d.ts +5 -0
  112. package/dist/tests/unit/parser/media-parser.test.d.ts.map +1 -0
  113. package/dist/tests/unit/parser/media-parser.test.js +241 -0
  114. package/dist/tests/unit/parser/primitive-parser.test.d.ts +5 -0
  115. package/dist/tests/unit/parser/primitive-parser.test.d.ts.map +1 -0
  116. package/dist/tests/unit/parser/primitive-parser.test.js +261 -0
  117. package/dist/tests/unit/parser/scanner.test.d.ts +5 -0
  118. package/dist/tests/unit/parser/scanner.test.d.ts.map +1 -0
  119. package/dist/tests/unit/parser/scanner.test.js +241 -0
  120. package/dist/tests/unit/parser/session-parser.test.d.ts +5 -0
  121. package/dist/tests/unit/parser/session-parser.test.d.ts.map +1 -0
  122. package/dist/tests/unit/parser/session-parser.test.js +346 -0
  123. package/dist/tests/unit/parser/time-parser.test.d.ts +5 -0
  124. package/dist/tests/unit/parser/time-parser.test.d.ts.map +1 -0
  125. package/dist/tests/unit/parser/time-parser.test.js +173 -0
  126. package/dist/tests/unit/serializer/attribute-serializer.test.d.ts +5 -0
  127. package/dist/tests/unit/serializer/attribute-serializer.test.d.ts.map +1 -0
  128. package/dist/tests/unit/serializer/attribute-serializer.test.js +78 -0
  129. package/dist/tests/unit/serializer/field-serializer.test.d.ts +5 -0
  130. package/dist/tests/unit/serializer/field-serializer.test.d.ts.map +1 -0
  131. package/dist/tests/unit/serializer/field-serializer.test.js +159 -0
  132. package/dist/tests/unit/serializer/media-serializer.test.d.ts +5 -0
  133. package/dist/tests/unit/serializer/media-serializer.test.d.ts.map +1 -0
  134. package/dist/tests/unit/serializer/media-serializer.test.js +155 -0
  135. package/dist/tests/unit/serializer/session-serializer.test.d.ts +5 -0
  136. package/dist/tests/unit/serializer/session-serializer.test.d.ts.map +1 -0
  137. package/dist/tests/unit/serializer/session-serializer.test.js +317 -0
  138. package/dist/tests/unit/serializer/time-serializer.test.d.ts +5 -0
  139. package/dist/tests/unit/serializer/time-serializer.test.d.ts.map +1 -0
  140. package/dist/tests/unit/serializer/time-serializer.test.js +115 -0
  141. package/dist/tests/unit/types/errors.test.d.ts +5 -0
  142. package/dist/tests/unit/types/errors.test.d.ts.map +1 -0
  143. package/dist/tests/unit/types/errors.test.js +127 -0
  144. package/dist/tests/unit/types/network.test.d.ts +5 -0
  145. package/dist/tests/unit/types/network.test.d.ts.map +1 -0
  146. package/dist/tests/unit/types/network.test.js +132 -0
  147. package/dist/tests/unit/types/primitives.test.d.ts +5 -0
  148. package/dist/tests/unit/types/primitives.test.d.ts.map +1 -0
  149. package/dist/tests/unit/types/primitives.test.js +108 -0
  150. package/dist/tests/unit/utils/address-parser.test.d.ts +5 -0
  151. package/dist/tests/unit/utils/address-parser.test.d.ts.map +1 -0
  152. package/dist/tests/unit/utils/address-parser.test.js +203 -0
  153. package/dist/tests/unit/utils/format-validators.test.d.ts +5 -0
  154. package/dist/tests/unit/utils/format-validators.test.d.ts.map +1 -0
  155. package/dist/tests/unit/utils/format-validators.test.js +224 -0
  156. package/dist/tests/unit/utils/line-reader.test.d.ts +5 -0
  157. package/dist/tests/unit/utils/line-reader.test.d.ts.map +1 -0
  158. package/dist/tests/unit/utils/line-reader.test.js +157 -0
  159. package/dist/tests/unit/utils/time-converter.test.d.ts +5 -0
  160. package/dist/tests/unit/utils/time-converter.test.d.ts.map +1 -0
  161. package/dist/tests/unit/utils/time-converter.test.js +190 -0
  162. package/dist/tests/unit/validator/media-validator.test.d.ts +5 -0
  163. package/dist/tests/unit/validator/media-validator.test.d.ts.map +1 -0
  164. package/dist/tests/unit/validator/media-validator.test.js +313 -0
  165. package/dist/tests/unit/validator/semantic-validator.test.d.ts +5 -0
  166. package/dist/tests/unit/validator/semantic-validator.test.d.ts.map +1 -0
  167. package/dist/tests/unit/validator/semantic-validator.test.js +262 -0
  168. package/dist/tests/unit/validator/session-validator.test.d.ts +5 -0
  169. package/dist/tests/unit/validator/session-validator.test.d.ts.map +1 -0
  170. package/dist/tests/unit/validator/session-validator.test.js +447 -0
  171. package/package.json +50 -0
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ /**
3
+ * TSDP - TypeScript SDP Library
4
+ *
5
+ * A complete, RFC 8866-compliant SDP (Session Description Protocol) library
6
+ * for TypeScript/JavaScript applications.
7
+ *
8
+ * Features:
9
+ * - Full RFC 8866 compliance
10
+ * - Type-safe with branded types
11
+ * - Fluent builder APIs
12
+ * - Comprehensive validation
13
+ * - Parse and serialize SDP
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { parseSessionDescription, serializeSessionDescription, SessionBuilder } from 'tsdp';
18
+ *
19
+ * // Parse SDP
20
+ * const sdp = parseSessionDescription(sdpString);
21
+ *
22
+ * // Build SDP
23
+ * const session = new SessionBuilder()
24
+ * .origin('alice', '123', '456', '192.168.1.1')
25
+ * .sessionName('My Call')
26
+ * .connection('192.168.1.100')
27
+ * .addAudioMedia(49170, 'RTP/AVP', ['0', '8'])
28
+ * .build();
29
+ *
30
+ * // Serialize SDP
31
+ * const sdpString = serializeSessionDescription(session);
32
+ *
33
+ * // Validate SDP
34
+ * const result = validateSdp(session);
35
+ * if (!result.valid) {
36
+ * console.error(result.errors);
37
+ * }
38
+ * ```
39
+ *
40
+ * @packageDocumentation
41
+ */
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.SdpError = exports.createTypedTime = exports.createNtpTime = exports.createUsername = exports.createSessionName = exports.createVersion = exports.isFQDNMulticastAddress = exports.isIP6MulticastAddress = exports.isIP4MulticastAddress = exports.isUnicastAddress = exports.isMulticastAddress = exports.createFQDNMulticastAddress = exports.createIP6MulticastAddress = exports.createIP4MulticastAddress = exports.createExtensionAddress = exports.createFQDN = exports.createIP6Address = exports.createIP4Address = exports.isDirectionAttribute = exports.isValueAttribute = exports.isPropertyAttribute = exports.createMaxptime = exports.createPtime = exports.createFmtp = exports.createRtpmap = exports.createInactive = exports.createSendonly = exports.createSendrecv = exports.createRecvonly = exports.createValueAttribute = exports.createPropertyAttribute = exports.createTimeDescription = exports.createTimezone = exports.createTimezoneAdjustment = exports.createRepeat = exports.createPermanentTiming = exports.createTiming = exports.createBandwidth = exports.createConnection = exports.createOrigin = exports.getPortNumbers = exports.getPortNumber = exports.isPortRange = exports.isSimplePort = exports.createMediaDescription = exports.createPortRange = exports.createSimplePort = exports.createMedia = exports.createMinimalSessionDescription = exports.createSessionDescription = void 0;
44
+ exports.validateSemanticConstraints = exports.validateSdp = exports.serializeMediaDescription = exports.serializeMediaField = exports.serializeAttributeField = exports.serializeTimeDescription = exports.serializeTimezoneField = exports.serializeRepeatField = exports.serializeTimingField = exports.serializeKeyField = exports.serializeBandwidthField = exports.serializeConnectionAddress = exports.serializeConnectionField = exports.serializePhoneField = exports.serializeEmailField = exports.serializeUriField = exports.serializeInformationField = exports.serializeSessionNameField = exports.serializeOriginField = exports.serializeVersionField = exports.serializeSessionDescription = exports.parseMediaDescription = exports.parseMediaField = exports.parseQualityValue = exports.parseFramerateValue = exports.parseMaxptimeValue = exports.parsePtimeValue = exports.parseFmtpValue = exports.parseRtpmapValue = exports.parseAttributeField = exports.parseTimeDescription = exports.parseTimezoneField = exports.parseRepeatField = exports.parseTimingField = exports.parseKeyField = exports.parseBandwidthField = exports.parseConnectionField = exports.parsePhoneField = exports.parseEmailField = exports.parseUriField = exports.parseInformationField = exports.parseSessionNameField = exports.parseOriginField = exports.parseVersionField = exports.parseSessionDescription = exports.BuilderError = exports.SerializationError = exports.ValidationError = exports.GrammarError = exports.ParseError = void 0;
45
+ exports.getLineTypeName = exports.isValidLineType = exports.formatLine = exports.joinLines = exports.parseLines = exports.parseLine = exports.splitLines = exports.normalizeTypedTime = exports.typedTimesEqual = exports.compareTypedTimes = exports.addTypedTimes = exports.secondsToTypedTime = exports.typedTimeToSeconds = exports.serializeTypedTime = exports.parseTypedTime = exports.detectAddressType = exports.parseUnicastAddress = exports.parseFQDN = exports.parseIP6Address = exports.parseIP4Address = exports.isIP6MulticastRange = exports.isIP4MulticastRange = exports.isFQDN = exports.isIP6Address = exports.isIP4Address = exports.videoBuilder = exports.audioBuilder = exports.mediaBuilder = exports.MediaBuilder = exports.sessionBuilder = exports.SessionBuilder = exports.validateAllMediaDescriptions = exports.validateMediaDescription = exports.invalidResult = exports.validResult = exports.validateSessionDescription = void 0;
46
+ // ============================================================================
47
+ // Core Types
48
+ // ============================================================================
49
+ // Session Description
50
+ var session_1 = require("./types/session");
51
+ Object.defineProperty(exports, "createSessionDescription", { enumerable: true, get: function () { return session_1.createSessionDescription; } });
52
+ Object.defineProperty(exports, "createMinimalSessionDescription", { enumerable: true, get: function () { return session_1.createMinimalSessionDescription; } });
53
+ // Media Description
54
+ var media_1 = require("./types/media");
55
+ Object.defineProperty(exports, "createMedia", { enumerable: true, get: function () { return media_1.createMedia; } });
56
+ Object.defineProperty(exports, "createSimplePort", { enumerable: true, get: function () { return media_1.createSimplePort; } });
57
+ Object.defineProperty(exports, "createPortRange", { enumerable: true, get: function () { return media_1.createPortRange; } });
58
+ Object.defineProperty(exports, "createMediaDescription", { enumerable: true, get: function () { return media_1.createMediaDescription; } });
59
+ Object.defineProperty(exports, "isSimplePort", { enumerable: true, get: function () { return media_1.isSimplePort; } });
60
+ Object.defineProperty(exports, "isPortRange", { enumerable: true, get: function () { return media_1.isPortRange; } });
61
+ Object.defineProperty(exports, "getPortNumber", { enumerable: true, get: function () { return media_1.getPortNumber; } });
62
+ Object.defineProperty(exports, "getPortNumbers", { enumerable: true, get: function () { return media_1.getPortNumbers; } });
63
+ // ============================================================================
64
+ // Field Types
65
+ // ============================================================================
66
+ var fields_1 = require("./types/fields");
67
+ Object.defineProperty(exports, "createOrigin", { enumerable: true, get: function () { return fields_1.createOrigin; } });
68
+ Object.defineProperty(exports, "createConnection", { enumerable: true, get: function () { return fields_1.createConnection; } });
69
+ Object.defineProperty(exports, "createBandwidth", { enumerable: true, get: function () { return fields_1.createBandwidth; } });
70
+ // ============================================================================
71
+ // Time Types
72
+ // ============================================================================
73
+ var time_1 = require("./types/time");
74
+ Object.defineProperty(exports, "createTiming", { enumerable: true, get: function () { return time_1.createTiming; } });
75
+ Object.defineProperty(exports, "createPermanentTiming", { enumerable: true, get: function () { return time_1.createPermanentTiming; } });
76
+ Object.defineProperty(exports, "createRepeat", { enumerable: true, get: function () { return time_1.createRepeat; } });
77
+ Object.defineProperty(exports, "createTimezoneAdjustment", { enumerable: true, get: function () { return time_1.createTimezoneAdjustment; } });
78
+ Object.defineProperty(exports, "createTimezone", { enumerable: true, get: function () { return time_1.createTimezone; } });
79
+ Object.defineProperty(exports, "createTimeDescription", { enumerable: true, get: function () { return time_1.createTimeDescription; } });
80
+ // ============================================================================
81
+ // Attribute Types
82
+ // ============================================================================
83
+ var attributes_1 = require("./types/attributes");
84
+ Object.defineProperty(exports, "createPropertyAttribute", { enumerable: true, get: function () { return attributes_1.createPropertyAttribute; } });
85
+ Object.defineProperty(exports, "createValueAttribute", { enumerable: true, get: function () { return attributes_1.createValueAttribute; } });
86
+ Object.defineProperty(exports, "createRecvonly", { enumerable: true, get: function () { return attributes_1.createRecvonly; } });
87
+ Object.defineProperty(exports, "createSendrecv", { enumerable: true, get: function () { return attributes_1.createSendrecv; } });
88
+ Object.defineProperty(exports, "createSendonly", { enumerable: true, get: function () { return attributes_1.createSendonly; } });
89
+ Object.defineProperty(exports, "createInactive", { enumerable: true, get: function () { return attributes_1.createInactive; } });
90
+ Object.defineProperty(exports, "createRtpmap", { enumerable: true, get: function () { return attributes_1.createRtpmap; } });
91
+ Object.defineProperty(exports, "createFmtp", { enumerable: true, get: function () { return attributes_1.createFmtp; } });
92
+ Object.defineProperty(exports, "createPtime", { enumerable: true, get: function () { return attributes_1.createPtime; } });
93
+ Object.defineProperty(exports, "createMaxptime", { enumerable: true, get: function () { return attributes_1.createMaxptime; } });
94
+ Object.defineProperty(exports, "isPropertyAttribute", { enumerable: true, get: function () { return attributes_1.isPropertyAttribute; } });
95
+ Object.defineProperty(exports, "isValueAttribute", { enumerable: true, get: function () { return attributes_1.isValueAttribute; } });
96
+ Object.defineProperty(exports, "isDirectionAttribute", { enumerable: true, get: function () { return attributes_1.isDirectionAttribute; } });
97
+ // ============================================================================
98
+ // Network Types
99
+ // ============================================================================
100
+ var network_1 = require("./types/network");
101
+ Object.defineProperty(exports, "createIP4Address", { enumerable: true, get: function () { return network_1.createIP4Address; } });
102
+ Object.defineProperty(exports, "createIP6Address", { enumerable: true, get: function () { return network_1.createIP6Address; } });
103
+ Object.defineProperty(exports, "createFQDN", { enumerable: true, get: function () { return network_1.createFQDN; } });
104
+ Object.defineProperty(exports, "createExtensionAddress", { enumerable: true, get: function () { return network_1.createExtensionAddress; } });
105
+ Object.defineProperty(exports, "createIP4MulticastAddress", { enumerable: true, get: function () { return network_1.createIP4MulticastAddress; } });
106
+ Object.defineProperty(exports, "createIP6MulticastAddress", { enumerable: true, get: function () { return network_1.createIP6MulticastAddress; } });
107
+ Object.defineProperty(exports, "createFQDNMulticastAddress", { enumerable: true, get: function () { return network_1.createFQDNMulticastAddress; } });
108
+ Object.defineProperty(exports, "isMulticastAddress", { enumerable: true, get: function () { return network_1.isMulticastAddress; } });
109
+ Object.defineProperty(exports, "isUnicastAddress", { enumerable: true, get: function () { return network_1.isUnicastAddress; } });
110
+ Object.defineProperty(exports, "isIP4MulticastAddress", { enumerable: true, get: function () { return network_1.isIP4MulticastAddress; } });
111
+ Object.defineProperty(exports, "isIP6MulticastAddress", { enumerable: true, get: function () { return network_1.isIP6MulticastAddress; } });
112
+ Object.defineProperty(exports, "isFQDNMulticastAddress", { enumerable: true, get: function () { return network_1.isFQDNMulticastAddress; } });
113
+ // ============================================================================
114
+ // Primitive Types
115
+ // ============================================================================
116
+ var primitives_1 = require("./types/primitives");
117
+ Object.defineProperty(exports, "createVersion", { enumerable: true, get: function () { return primitives_1.createVersion; } });
118
+ Object.defineProperty(exports, "createSessionName", { enumerable: true, get: function () { return primitives_1.createSessionName; } });
119
+ Object.defineProperty(exports, "createUsername", { enumerable: true, get: function () { return primitives_1.createUsername; } });
120
+ Object.defineProperty(exports, "createNtpTime", { enumerable: true, get: function () { return primitives_1.createNtpTime; } });
121
+ Object.defineProperty(exports, "createTypedTime", { enumerable: true, get: function () { return primitives_1.createTypedTime; } });
122
+ // ============================================================================
123
+ // Error Types
124
+ // ============================================================================
125
+ var errors_1 = require("./types/errors");
126
+ Object.defineProperty(exports, "SdpError", { enumerable: true, get: function () { return errors_1.SdpError; } });
127
+ Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return errors_1.ParseError; } });
128
+ Object.defineProperty(exports, "GrammarError", { enumerable: true, get: function () { return errors_1.GrammarError; } });
129
+ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_1.ValidationError; } });
130
+ Object.defineProperty(exports, "SerializationError", { enumerable: true, get: function () { return errors_1.SerializationError; } });
131
+ Object.defineProperty(exports, "BuilderError", { enumerable: true, get: function () { return errors_1.BuilderError; } });
132
+ // ============================================================================
133
+ // Parser
134
+ // ============================================================================
135
+ var session_parser_1 = require("./parser/session-parser");
136
+ Object.defineProperty(exports, "parseSessionDescription", { enumerable: true, get: function () { return session_parser_1.parseSessionDescription; } });
137
+ // Re-export specific parsers for advanced use cases
138
+ var field_parser_1 = require("./parser/field-parser");
139
+ Object.defineProperty(exports, "parseVersionField", { enumerable: true, get: function () { return field_parser_1.parseVersionField; } });
140
+ Object.defineProperty(exports, "parseOriginField", { enumerable: true, get: function () { return field_parser_1.parseOriginField; } });
141
+ Object.defineProperty(exports, "parseSessionNameField", { enumerable: true, get: function () { return field_parser_1.parseSessionNameField; } });
142
+ Object.defineProperty(exports, "parseInformationField", { enumerable: true, get: function () { return field_parser_1.parseInformationField; } });
143
+ Object.defineProperty(exports, "parseUriField", { enumerable: true, get: function () { return field_parser_1.parseUriField; } });
144
+ Object.defineProperty(exports, "parseEmailField", { enumerable: true, get: function () { return field_parser_1.parseEmailField; } });
145
+ Object.defineProperty(exports, "parsePhoneField", { enumerable: true, get: function () { return field_parser_1.parsePhoneField; } });
146
+ Object.defineProperty(exports, "parseConnectionField", { enumerable: true, get: function () { return field_parser_1.parseConnectionField; } });
147
+ Object.defineProperty(exports, "parseBandwidthField", { enumerable: true, get: function () { return field_parser_1.parseBandwidthField; } });
148
+ Object.defineProperty(exports, "parseKeyField", { enumerable: true, get: function () { return field_parser_1.parseKeyField; } });
149
+ var time_parser_1 = require("./parser/time-parser");
150
+ Object.defineProperty(exports, "parseTimingField", { enumerable: true, get: function () { return time_parser_1.parseTimingField; } });
151
+ Object.defineProperty(exports, "parseRepeatField", { enumerable: true, get: function () { return time_parser_1.parseRepeatField; } });
152
+ Object.defineProperty(exports, "parseTimezoneField", { enumerable: true, get: function () { return time_parser_1.parseTimezoneField; } });
153
+ Object.defineProperty(exports, "parseTimeDescription", { enumerable: true, get: function () { return time_parser_1.parseTimeDescription; } });
154
+ var attribute_parser_1 = require("./parser/attribute-parser");
155
+ Object.defineProperty(exports, "parseAttributeField", { enumerable: true, get: function () { return attribute_parser_1.parseAttributeField; } });
156
+ Object.defineProperty(exports, "parseRtpmapValue", { enumerable: true, get: function () { return attribute_parser_1.parseRtpmapValue; } });
157
+ Object.defineProperty(exports, "parseFmtpValue", { enumerable: true, get: function () { return attribute_parser_1.parseFmtpValue; } });
158
+ Object.defineProperty(exports, "parsePtimeValue", { enumerable: true, get: function () { return attribute_parser_1.parsePtimeValue; } });
159
+ Object.defineProperty(exports, "parseMaxptimeValue", { enumerable: true, get: function () { return attribute_parser_1.parseMaxptimeValue; } });
160
+ Object.defineProperty(exports, "parseFramerateValue", { enumerable: true, get: function () { return attribute_parser_1.parseFramerateValue; } });
161
+ Object.defineProperty(exports, "parseQualityValue", { enumerable: true, get: function () { return attribute_parser_1.parseQualityValue; } });
162
+ var media_parser_1 = require("./parser/media-parser");
163
+ Object.defineProperty(exports, "parseMediaField", { enumerable: true, get: function () { return media_parser_1.parseMediaField; } });
164
+ Object.defineProperty(exports, "parseMediaDescription", { enumerable: true, get: function () { return media_parser_1.parseMediaDescription; } });
165
+ // ============================================================================
166
+ // Serializer
167
+ // ============================================================================
168
+ var session_serializer_1 = require("./serializer/session-serializer");
169
+ Object.defineProperty(exports, "serializeSessionDescription", { enumerable: true, get: function () { return session_serializer_1.serializeSessionDescription; } });
170
+ // Re-export specific serializers for advanced use cases
171
+ var field_serializer_1 = require("./serializer/field-serializer");
172
+ Object.defineProperty(exports, "serializeVersionField", { enumerable: true, get: function () { return field_serializer_1.serializeVersionField; } });
173
+ Object.defineProperty(exports, "serializeOriginField", { enumerable: true, get: function () { return field_serializer_1.serializeOriginField; } });
174
+ Object.defineProperty(exports, "serializeSessionNameField", { enumerable: true, get: function () { return field_serializer_1.serializeSessionNameField; } });
175
+ Object.defineProperty(exports, "serializeInformationField", { enumerable: true, get: function () { return field_serializer_1.serializeInformationField; } });
176
+ Object.defineProperty(exports, "serializeUriField", { enumerable: true, get: function () { return field_serializer_1.serializeUriField; } });
177
+ Object.defineProperty(exports, "serializeEmailField", { enumerable: true, get: function () { return field_serializer_1.serializeEmailField; } });
178
+ Object.defineProperty(exports, "serializePhoneField", { enumerable: true, get: function () { return field_serializer_1.serializePhoneField; } });
179
+ Object.defineProperty(exports, "serializeConnectionField", { enumerable: true, get: function () { return field_serializer_1.serializeConnectionField; } });
180
+ Object.defineProperty(exports, "serializeConnectionAddress", { enumerable: true, get: function () { return field_serializer_1.serializeConnectionAddress; } });
181
+ Object.defineProperty(exports, "serializeBandwidthField", { enumerable: true, get: function () { return field_serializer_1.serializeBandwidthField; } });
182
+ Object.defineProperty(exports, "serializeKeyField", { enumerable: true, get: function () { return field_serializer_1.serializeKeyField; } });
183
+ var time_serializer_1 = require("./serializer/time-serializer");
184
+ Object.defineProperty(exports, "serializeTimingField", { enumerable: true, get: function () { return time_serializer_1.serializeTimingField; } });
185
+ Object.defineProperty(exports, "serializeRepeatField", { enumerable: true, get: function () { return time_serializer_1.serializeRepeatField; } });
186
+ Object.defineProperty(exports, "serializeTimezoneField", { enumerable: true, get: function () { return time_serializer_1.serializeTimezoneField; } });
187
+ Object.defineProperty(exports, "serializeTimeDescription", { enumerable: true, get: function () { return time_serializer_1.serializeTimeDescription; } });
188
+ var attribute_serializer_1 = require("./serializer/attribute-serializer");
189
+ Object.defineProperty(exports, "serializeAttributeField", { enumerable: true, get: function () { return attribute_serializer_1.serializeAttributeField; } });
190
+ var media_serializer_1 = require("./serializer/media-serializer");
191
+ Object.defineProperty(exports, "serializeMediaField", { enumerable: true, get: function () { return media_serializer_1.serializeMediaField; } });
192
+ Object.defineProperty(exports, "serializeMediaDescription", { enumerable: true, get: function () { return media_serializer_1.serializeMediaDescription; } });
193
+ // ============================================================================
194
+ // Validator
195
+ // ============================================================================
196
+ var semantic_validator_1 = require("./validator/semantic-validator");
197
+ Object.defineProperty(exports, "validateSdp", { enumerable: true, get: function () { return semantic_validator_1.validateSdp; } });
198
+ Object.defineProperty(exports, "validateSemanticConstraints", { enumerable: true, get: function () { return semantic_validator_1.validateSemanticConstraints; } });
199
+ var session_validator_1 = require("./validator/session-validator");
200
+ Object.defineProperty(exports, "validateSessionDescription", { enumerable: true, get: function () { return session_validator_1.validateSessionDescription; } });
201
+ Object.defineProperty(exports, "validResult", { enumerable: true, get: function () { return session_validator_1.validResult; } });
202
+ Object.defineProperty(exports, "invalidResult", { enumerable: true, get: function () { return session_validator_1.invalidResult; } });
203
+ var media_validator_1 = require("./validator/media-validator");
204
+ Object.defineProperty(exports, "validateMediaDescription", { enumerable: true, get: function () { return media_validator_1.validateMediaDescription; } });
205
+ Object.defineProperty(exports, "validateAllMediaDescriptions", { enumerable: true, get: function () { return media_validator_1.validateAllMediaDescriptions; } });
206
+ // ============================================================================
207
+ // Builder
208
+ // ============================================================================
209
+ var session_builder_1 = require("./builder/session-builder");
210
+ Object.defineProperty(exports, "SessionBuilder", { enumerable: true, get: function () { return session_builder_1.SessionBuilder; } });
211
+ Object.defineProperty(exports, "sessionBuilder", { enumerable: true, get: function () { return session_builder_1.sessionBuilder; } });
212
+ var media_builder_1 = require("./builder/media-builder");
213
+ Object.defineProperty(exports, "MediaBuilder", { enumerable: true, get: function () { return media_builder_1.MediaBuilder; } });
214
+ Object.defineProperty(exports, "mediaBuilder", { enumerable: true, get: function () { return media_builder_1.mediaBuilder; } });
215
+ Object.defineProperty(exports, "audioBuilder", { enumerable: true, get: function () { return media_builder_1.audioBuilder; } });
216
+ Object.defineProperty(exports, "videoBuilder", { enumerable: true, get: function () { return media_builder_1.videoBuilder; } });
217
+ // ============================================================================
218
+ // Utilities
219
+ // ============================================================================
220
+ // Address parsing utilities
221
+ var address_parser_1 = require("./utils/address-parser");
222
+ Object.defineProperty(exports, "isIP4Address", { enumerable: true, get: function () { return address_parser_1.isIP4Address; } });
223
+ Object.defineProperty(exports, "isIP6Address", { enumerable: true, get: function () { return address_parser_1.isIP6Address; } });
224
+ Object.defineProperty(exports, "isFQDN", { enumerable: true, get: function () { return address_parser_1.isFQDN; } });
225
+ Object.defineProperty(exports, "isIP4MulticastRange", { enumerable: true, get: function () { return address_parser_1.isIP4MulticastAddress; } });
226
+ Object.defineProperty(exports, "isIP6MulticastRange", { enumerable: true, get: function () { return address_parser_1.isIP6MulticastAddress; } });
227
+ Object.defineProperty(exports, "parseIP4Address", { enumerable: true, get: function () { return address_parser_1.parseIP4Address; } });
228
+ Object.defineProperty(exports, "parseIP6Address", { enumerable: true, get: function () { return address_parser_1.parseIP6Address; } });
229
+ Object.defineProperty(exports, "parseFQDN", { enumerable: true, get: function () { return address_parser_1.parseFQDN; } });
230
+ Object.defineProperty(exports, "parseUnicastAddress", { enumerable: true, get: function () { return address_parser_1.parseUnicastAddress; } });
231
+ Object.defineProperty(exports, "detectAddressType", { enumerable: true, get: function () { return address_parser_1.detectAddressType; } });
232
+ // Time conversion utilities
233
+ var time_converter_1 = require("./utils/time-converter");
234
+ Object.defineProperty(exports, "parseTypedTime", { enumerable: true, get: function () { return time_converter_1.parseTypedTime; } });
235
+ Object.defineProperty(exports, "serializeTypedTime", { enumerable: true, get: function () { return time_converter_1.serializeTypedTime; } });
236
+ Object.defineProperty(exports, "typedTimeToSeconds", { enumerable: true, get: function () { return time_converter_1.typedTimeToSeconds; } });
237
+ Object.defineProperty(exports, "secondsToTypedTime", { enumerable: true, get: function () { return time_converter_1.secondsToTypedTime; } });
238
+ Object.defineProperty(exports, "addTypedTimes", { enumerable: true, get: function () { return time_converter_1.addTypedTimes; } });
239
+ Object.defineProperty(exports, "compareTypedTimes", { enumerable: true, get: function () { return time_converter_1.compareTypedTimes; } });
240
+ Object.defineProperty(exports, "typedTimesEqual", { enumerable: true, get: function () { return time_converter_1.typedTimesEqual; } });
241
+ Object.defineProperty(exports, "normalizeTypedTime", { enumerable: true, get: function () { return time_converter_1.normalizeTypedTime; } });
242
+ // Line parsing utilities (for advanced use)
243
+ var line_reader_1 = require("./utils/line-reader");
244
+ Object.defineProperty(exports, "splitLines", { enumerable: true, get: function () { return line_reader_1.splitLines; } });
245
+ Object.defineProperty(exports, "parseLine", { enumerable: true, get: function () { return line_reader_1.parseLine; } });
246
+ Object.defineProperty(exports, "parseLines", { enumerable: true, get: function () { return line_reader_1.parseLines; } });
247
+ Object.defineProperty(exports, "joinLines", { enumerable: true, get: function () { return line_reader_1.joinLines; } });
248
+ Object.defineProperty(exports, "formatLine", { enumerable: true, get: function () { return line_reader_1.formatLine; } });
249
+ Object.defineProperty(exports, "isValidLineType", { enumerable: true, get: function () { return line_reader_1.isValidLineType; } });
250
+ Object.defineProperty(exports, "getLineTypeName", { enumerable: true, get: function () { return line_reader_1.getLineTypeName; } });
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Attribute parsers for SDP (RFC 8866)
3
+ *
4
+ * Parsers for SDP attributes (a= fields)
5
+ */
6
+ import { Scanner } from './scanner';
7
+ import { Attribute, RtpmapValue, FmtpValue } from '../types/attributes';
8
+ /**
9
+ * Parse attribute field
10
+ *
11
+ * Format:
12
+ * - Property attribute: a=<attribute-name>
13
+ * - Value attribute: a=<attribute-name>:<attribute-value>
14
+ *
15
+ * Property attributes have no value (e.g., a=recvonly, a=sendrecv).
16
+ * Value attributes have a value after colon (e.g., a=rtpmap:0 PCMU/8000).
17
+ *
18
+ * @param scanner - Scanner instance
19
+ * @returns Attribute object
20
+ * @throws ParseError if invalid format
21
+ */
22
+ export declare function parseAttributeField(scanner: Scanner): Attribute;
23
+ /**
24
+ * Parse rtpmap attribute value
25
+ *
26
+ * Format: <payload-type> <encoding-name>/<clock-rate>[/<encoding-params>]
27
+ *
28
+ * Examples:
29
+ * - "0 PCMU/8000"
30
+ * - "96 H264/90000"
31
+ * - "97 L16/8000/2" (2 channels)
32
+ *
33
+ * @param value - rtpmap attribute value string
34
+ * @returns Parsed RtpmapValue
35
+ * @throws ParseError if invalid format
36
+ */
37
+ export declare function parseRtpmapValue(value: string): RtpmapValue;
38
+ /**
39
+ * Parse fmtp attribute value
40
+ *
41
+ * Format: <format> <format-specific-params>
42
+ *
43
+ * Examples:
44
+ * - "96 profile-level-id=42e01f;packetization-mode=1"
45
+ * - "97 apt=96"
46
+ *
47
+ * @param value - fmtp attribute value string
48
+ * @returns Parsed FmtpValue
49
+ * @throws ParseError if invalid format
50
+ */
51
+ export declare function parseFmtpValue(value: string): FmtpValue;
52
+ /**
53
+ * Parse ptime attribute value
54
+ *
55
+ * Format: <packet-time-in-milliseconds>
56
+ *
57
+ * RFC 8866 Section 6.4: ptime-value = non-zero-int-or-real
58
+ * Decimal values are allowed (e.g., "20.5")
59
+ *
60
+ * @param value - ptime attribute value string
61
+ * @returns Packet time in milliseconds (can be fractional)
62
+ * @throws ParseError if invalid
63
+ */
64
+ export declare function parsePtimeValue(value: string): number;
65
+ /**
66
+ * Parse maxptime attribute value
67
+ *
68
+ * Format: <max-packet-time-in-milliseconds>
69
+ *
70
+ * RFC 8866 Section 6.5: maxptime-value = non-zero-int-or-real
71
+ * Decimal values are allowed (e.g., "40.0")
72
+ *
73
+ * @param value - maxptime attribute value string
74
+ * @returns Maximum packet time in milliseconds (can be fractional)
75
+ * @throws ParseError if invalid
76
+ */
77
+ export declare function parseMaxptimeValue(value: string): number;
78
+ /**
79
+ * Parse framerate attribute value
80
+ *
81
+ * Format: <frames-per-second>
82
+ *
83
+ * @param value - framerate attribute value string
84
+ * @returns Frame rate (frames per second)
85
+ * @throws ParseError if invalid
86
+ */
87
+ export declare function parseFramerateValue(value: string): number;
88
+ /**
89
+ * Parse quality attribute value
90
+ *
91
+ * Format: <quality-value>
92
+ *
93
+ * Quality is 0-10, where 10 is best quality.
94
+ *
95
+ * @param value - quality attribute value string
96
+ * @returns Quality value (0-10)
97
+ * @throws ParseError if invalid
98
+ */
99
+ export declare function parseQualityValue(value: string): number;
100
+ //# sourceMappingURL=attribute-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attribute-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/attribute-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,SAAS,EAOT,WAAW,EACX,SAAS,EAOV,MAAM,qBAAqB,CAAC;AAM7B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAiC/D;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CA8D3D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CA2BvD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYvD"}
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ /**
3
+ * Attribute parsers for SDP (RFC 8866)
4
+ *
5
+ * Parsers for SDP attributes (a= fields)
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.parseAttributeField = parseAttributeField;
9
+ exports.parseRtpmapValue = parseRtpmapValue;
10
+ exports.parseFmtpValue = parseFmtpValue;
11
+ exports.parsePtimeValue = parsePtimeValue;
12
+ exports.parseMaxptimeValue = parseMaxptimeValue;
13
+ exports.parseFramerateValue = parseFramerateValue;
14
+ exports.parseQualityValue = parseQualityValue;
15
+ const primitive_parser_1 = require("./primitive-parser");
16
+ const errors_1 = require("../types/errors");
17
+ const attributes_1 = require("../types/attributes");
18
+ // ============================================================================
19
+ // Attribute Field Parser (a=)
20
+ // ============================================================================
21
+ /**
22
+ * Parse attribute field
23
+ *
24
+ * Format:
25
+ * - Property attribute: a=<attribute-name>
26
+ * - Value attribute: a=<attribute-name>:<attribute-value>
27
+ *
28
+ * Property attributes have no value (e.g., a=recvonly, a=sendrecv).
29
+ * Value attributes have a value after colon (e.g., a=rtpmap:0 PCMU/8000).
30
+ *
31
+ * @param scanner - Scanner instance
32
+ * @returns Attribute object
33
+ * @throws ParseError if invalid format
34
+ */
35
+ function parseAttributeField(scanner) {
36
+ const start = scanner.getPosition();
37
+ // Parse attribute name (token up to : or end of line)
38
+ const name = (0, primitive_parser_1.parseToken)(scanner);
39
+ // Check for colon indicating value attribute
40
+ const ch = scanner.peek();
41
+ if (ch === ':') {
42
+ // Value attribute
43
+ scanner.advance(); // consume ':'
44
+ // Read value until end of line
45
+ const value = scanner.readUntil(/[\r\n]/);
46
+ return (0, attributes_1.createValueAttribute)(name, value);
47
+ }
48
+ else {
49
+ // Property attribute (no value)
50
+ // Return predefined attributes for known types
51
+ switch (name) {
52
+ case 'recvonly':
53
+ return (0, attributes_1.createRecvonly)();
54
+ case 'sendrecv':
55
+ return (0, attributes_1.createSendrecv)();
56
+ case 'sendonly':
57
+ return (0, attributes_1.createSendonly)();
58
+ case 'inactive':
59
+ return (0, attributes_1.createInactive)();
60
+ default:
61
+ return (0, attributes_1.createPropertyAttribute)(name);
62
+ }
63
+ }
64
+ }
65
+ // ============================================================================
66
+ // Specialized Attribute Value Parsers
67
+ // ============================================================================
68
+ /**
69
+ * Parse rtpmap attribute value
70
+ *
71
+ * Format: <payload-type> <encoding-name>/<clock-rate>[/<encoding-params>]
72
+ *
73
+ * Examples:
74
+ * - "0 PCMU/8000"
75
+ * - "96 H264/90000"
76
+ * - "97 L16/8000/2" (2 channels)
77
+ *
78
+ * @param value - rtpmap attribute value string
79
+ * @returns Parsed RtpmapValue
80
+ * @throws ParseError if invalid format
81
+ */
82
+ function parseRtpmapValue(value) {
83
+ // Split into payload type and encoding spec
84
+ const parts = value.split(/\s+/);
85
+ if (parts.length !== 2) {
86
+ throw new errors_1.ParseError(`Invalid rtpmap format: expected "<payload-type> <encoding-spec>", got "${value}"`, 0, 0);
87
+ }
88
+ const payloadType = parseInt(parts[0], 10);
89
+ if (isNaN(payloadType) || payloadType < 0 || payloadType > 127) {
90
+ throw new errors_1.ParseError(`Invalid payload type: ${parts[0]} (expected 0-127)`, 0, 0);
91
+ }
92
+ // Parse encoding spec: <encoding-name>/<clock-rate>[/<encoding-params>]
93
+ const encodingParts = parts[1].split('/');
94
+ if (encodingParts.length < 2) {
95
+ throw new errors_1.ParseError(`Invalid encoding spec: expected "<encoding-name>/<clock-rate>", got "${parts[1]}"`, 0, 0);
96
+ }
97
+ const encodingName = encodingParts[0];
98
+ const clockRate = parseInt(encodingParts[1], 10);
99
+ if (isNaN(clockRate) || clockRate <= 0) {
100
+ throw new errors_1.ParseError(`Invalid clock rate: ${encodingParts[1]} (must be positive)`, 0, 0);
101
+ }
102
+ // Optional encoding parameters (e.g., number of audio channels)
103
+ let encodingParams;
104
+ if (encodingParts.length > 2) {
105
+ encodingParams = parseInt(encodingParts[2], 10);
106
+ if (isNaN(encodingParams) || encodingParams <= 0) {
107
+ throw new errors_1.ParseError(`Invalid encoding parameters: ${encodingParts[2]} (must be positive)`, 0, 0);
108
+ }
109
+ }
110
+ return {
111
+ payloadType,
112
+ encodingName,
113
+ clockRate,
114
+ encodingParams,
115
+ };
116
+ }
117
+ /**
118
+ * Parse fmtp attribute value
119
+ *
120
+ * Format: <format> <format-specific-params>
121
+ *
122
+ * Examples:
123
+ * - "96 profile-level-id=42e01f;packetization-mode=1"
124
+ * - "97 apt=96"
125
+ *
126
+ * @param value - fmtp attribute value string
127
+ * @returns Parsed FmtpValue
128
+ * @throws ParseError if invalid format
129
+ */
130
+ function parseFmtpValue(value) {
131
+ // Split on first whitespace
132
+ const spaceIndex = value.search(/\s/);
133
+ if (spaceIndex === -1) {
134
+ throw new errors_1.ParseError(`Invalid fmtp format: expected "<format> <parameters>", got "${value}"`, 0, 0);
135
+ }
136
+ const format = value.substring(0, spaceIndex);
137
+ const parameters = value.substring(spaceIndex + 1).trim();
138
+ if (parameters.length === 0) {
139
+ throw new errors_1.ParseError(`Invalid fmtp format: parameters cannot be empty`, 0, 0);
140
+ }
141
+ return {
142
+ format,
143
+ parameters,
144
+ };
145
+ }
146
+ /**
147
+ * Parse ptime attribute value
148
+ *
149
+ * Format: <packet-time-in-milliseconds>
150
+ *
151
+ * RFC 8866 Section 6.4: ptime-value = non-zero-int-or-real
152
+ * Decimal values are allowed (e.g., "20.5")
153
+ *
154
+ * @param value - ptime attribute value string
155
+ * @returns Packet time in milliseconds (can be fractional)
156
+ * @throws ParseError if invalid
157
+ */
158
+ function parsePtimeValue(value) {
159
+ const ptime = parseFloat(value);
160
+ if (isNaN(ptime) || ptime <= 0) {
161
+ throw new errors_1.ParseError(`Invalid ptime value: ${value} (must be positive number)`, 0, 0);
162
+ }
163
+ return ptime;
164
+ }
165
+ /**
166
+ * Parse maxptime attribute value
167
+ *
168
+ * Format: <max-packet-time-in-milliseconds>
169
+ *
170
+ * RFC 8866 Section 6.5: maxptime-value = non-zero-int-or-real
171
+ * Decimal values are allowed (e.g., "40.0")
172
+ *
173
+ * @param value - maxptime attribute value string
174
+ * @returns Maximum packet time in milliseconds (can be fractional)
175
+ * @throws ParseError if invalid
176
+ */
177
+ function parseMaxptimeValue(value) {
178
+ const maxptime = parseFloat(value);
179
+ if (isNaN(maxptime) || maxptime <= 0) {
180
+ throw new errors_1.ParseError(`Invalid maxptime value: ${value} (must be positive number)`, 0, 0);
181
+ }
182
+ return maxptime;
183
+ }
184
+ /**
185
+ * Parse framerate attribute value
186
+ *
187
+ * Format: <frames-per-second>
188
+ *
189
+ * @param value - framerate attribute value string
190
+ * @returns Frame rate (frames per second)
191
+ * @throws ParseError if invalid
192
+ */
193
+ function parseFramerateValue(value) {
194
+ const framerate = parseFloat(value);
195
+ if (isNaN(framerate) || framerate <= 0) {
196
+ throw new errors_1.ParseError(`Invalid framerate value: ${value} (must be positive number)`, 0, 0);
197
+ }
198
+ return framerate;
199
+ }
200
+ /**
201
+ * Parse quality attribute value
202
+ *
203
+ * Format: <quality-value>
204
+ *
205
+ * Quality is 0-10, where 10 is best quality.
206
+ *
207
+ * @param value - quality attribute value string
208
+ * @returns Quality value (0-10)
209
+ * @throws ParseError if invalid
210
+ */
211
+ function parseQualityValue(value) {
212
+ const quality = parseInt(value, 10);
213
+ if (isNaN(quality) || quality < 0 || quality > 10) {
214
+ throw new errors_1.ParseError(`Invalid quality value: ${value} (must be 0-10)`, 0, 0);
215
+ }
216
+ return quality;
217
+ }