@tomgiee/tsdp 1.0.1 → 1.1.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 (68) hide show
  1. package/README.md +0 -39
  2. package/dist/src/builder/media-builder.d.ts.map +1 -1
  3. package/dist/src/builder/media-builder.js +5 -12
  4. package/dist/src/builder/session-builder.d.ts.map +1 -1
  5. package/dist/src/builder/session-builder.js +4 -14
  6. package/dist/src/index.d.ts +6 -10
  7. package/dist/src/index.d.ts.map +1 -1
  8. package/dist/src/index.js +37 -49
  9. package/dist/src/parser/core.d.ts +366 -0
  10. package/dist/src/parser/core.d.ts.map +1 -0
  11. package/dist/src/parser/core.js +802 -0
  12. package/dist/src/parser/field-parser.d.ts +51 -8
  13. package/dist/src/parser/field-parser.d.ts.map +1 -1
  14. package/dist/src/parser/field-parser.js +91 -23
  15. package/dist/src/parser/media-parser.d.ts +1 -1
  16. package/dist/src/parser/media-parser.d.ts.map +1 -1
  17. package/dist/src/parser/media-parser.js +9 -15
  18. package/dist/src/parser/session-parser.d.ts.map +1 -1
  19. package/dist/src/parser/session-parser.js +16 -17
  20. package/dist/src/parser/time-parser.d.ts +1 -1
  21. package/dist/src/parser/time-parser.d.ts.map +1 -1
  22. package/dist/src/parser/time-parser.js +8 -8
  23. package/dist/src/serializer/fields.d.ts +167 -0
  24. package/dist/src/serializer/fields.d.ts.map +1 -0
  25. package/dist/src/serializer/fields.js +320 -0
  26. package/dist/src/serializer/media-serializer.js +6 -7
  27. package/dist/src/serializer/session-serializer.js +13 -15
  28. package/dist/src/types/attributes.d.ts.map +1 -1
  29. package/dist/src/types/fields.d.ts +5 -5
  30. package/dist/src/types/fields.d.ts.map +1 -1
  31. package/dist/src/types/fields.js +4 -4
  32. package/dist/src/types/media.d.ts +9 -10
  33. package/dist/src/types/media.d.ts.map +1 -1
  34. package/dist/src/types/media.js +2 -4
  35. package/dist/src/types/network.d.ts +15 -56
  36. package/dist/src/types/network.d.ts.map +1 -1
  37. package/dist/src/types/network.js +3 -34
  38. package/dist/src/types/primitives.d.ts +3 -147
  39. package/dist/src/types/primitives.d.ts.map +1 -1
  40. package/dist/src/types/primitives.js +2 -171
  41. package/dist/src/types/session.d.ts +14 -14
  42. package/dist/src/types/session.d.ts.map +1 -1
  43. package/dist/src/types/time.d.ts +4 -4
  44. package/dist/src/types/time.d.ts.map +1 -1
  45. package/dist/src/types/time.js +8 -6
  46. package/dist/src/utils/address-parser.d.ts +4 -4
  47. package/dist/src/utils/address-parser.d.ts.map +1 -1
  48. package/dist/src/utils/address-parser.js +9 -16
  49. package/dist/src/validator/validator.d.ts +94 -0
  50. package/dist/src/validator/validator.d.ts.map +1 -0
  51. package/dist/src/validator/validator.js +573 -0
  52. package/dist/tests/unit/parser/attribute-parser.test.js +106 -107
  53. package/dist/tests/unit/parser/field-parser.test.js +66 -66
  54. package/dist/tests/unit/parser/media-parser.test.js +38 -38
  55. package/dist/tests/unit/parser/primitive-parser.test.js +89 -90
  56. package/dist/tests/unit/parser/scanner.test.js +32 -32
  57. package/dist/tests/unit/parser/time-parser.test.js +22 -22
  58. package/dist/tests/unit/serializer/attribute-serializer.test.js +22 -22
  59. package/dist/tests/unit/serializer/field-serializer.test.js +57 -57
  60. package/dist/tests/unit/serializer/media-serializer.test.js +5 -6
  61. package/dist/tests/unit/serializer/session-serializer.test.js +24 -24
  62. package/dist/tests/unit/serializer/time-serializer.test.js +16 -16
  63. package/dist/tests/unit/types/network.test.js +21 -56
  64. package/dist/tests/unit/types/primitives.test.js +0 -39
  65. package/dist/tests/unit/validator/media-validator.test.js +34 -35
  66. package/dist/tests/unit/validator/semantic-validator.test.js +36 -37
  67. package/dist/tests/unit/validator/session-validator.test.js +54 -54
  68. package/package.json +1 -1
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Parsers for individual SDP field types (v=, o=, s=, i=, u=, e=, p=, c=, b=, k=)
5
5
  */
6
- import { Scanner } from './scanner';
7
- import { Version, SessionName, Information, URI, Email, Phone, Key } from '../types/primitives';
6
+ import { Scanner } from './core';
7
+ import { Version } from '../types/primitives';
8
8
  import { Origin, Connection, Bandwidth } from '../types/fields';
9
9
  /**
10
10
  * Parse version field
@@ -37,7 +37,7 @@ export declare function parseOriginField(scanner: Scanner): Origin;
37
37
  * @returns SessionName
38
38
  * @throws ParseError if empty
39
39
  */
40
- export declare function parseSessionNameField(scanner: Scanner): SessionName;
40
+ export declare function parseSessionNameField(scanner: Scanner): string;
41
41
  /**
42
42
  * Parse information field
43
43
  *
@@ -46,7 +46,7 @@ export declare function parseSessionNameField(scanner: Scanner): SessionName;
46
46
  * @param scanner - Scanner instance
47
47
  * @returns Information string
48
48
  */
49
- export declare function parseInformationField(scanner: Scanner): Information;
49
+ export declare function parseInformationField(scanner: Scanner): string;
50
50
  /**
51
51
  * Parse URI field
52
52
  *
@@ -55,7 +55,7 @@ export declare function parseInformationField(scanner: Scanner): Information;
55
55
  * @param scanner - Scanner instance
56
56
  * @returns URI string
57
57
  */
58
- export declare function parseUriField(scanner: Scanner): URI;
58
+ export declare function parseUriField(scanner: Scanner): string;
59
59
  /**
60
60
  * Parse email field
61
61
  *
@@ -64,7 +64,7 @@ export declare function parseUriField(scanner: Scanner): URI;
64
64
  * @param scanner - Scanner instance
65
65
  * @returns Email string
66
66
  */
67
- export declare function parseEmailField(scanner: Scanner): Email;
67
+ export declare function parseEmailField(scanner: Scanner): string;
68
68
  /**
69
69
  * Parse phone field
70
70
  *
@@ -73,7 +73,7 @@ export declare function parseEmailField(scanner: Scanner): Email;
73
73
  * @param scanner - Scanner instance
74
74
  * @returns Phone string
75
75
  */
76
- export declare function parsePhoneField(scanner: Scanner): Phone;
76
+ export declare function parsePhoneField(scanner: Scanner): string;
77
77
  /**
78
78
  * Parse connection field
79
79
  *
@@ -120,5 +120,48 @@ export declare function parseBandwidthField(scanner: Scanner): Bandwidth;
120
120
  * @param scanner - Scanner instance
121
121
  * @returns Key string
122
122
  */
123
- export declare function parseKeyField(scanner: Scanner): Key;
123
+ export declare function parseKeyField(scanner: Scanner): string;
124
+ /**
125
+ * Parse session name directly from pre-split line value
126
+ *
127
+ * @param value - The line value (everything after "s=")
128
+ * @returns SessionName
129
+ * @throws ParseError if empty
130
+ */
131
+ export declare function parseSessionNameDirect(value: string): string;
132
+ /**
133
+ * Parse information directly from pre-split line value
134
+ *
135
+ * @param value - The line value (everything after "i=")
136
+ * @returns Information string
137
+ */
138
+ export declare function parseInformationDirect(value: string): string;
139
+ /**
140
+ * Parse URI directly from pre-split line value
141
+ *
142
+ * @param value - The line value (everything after "u=")
143
+ * @returns URI string
144
+ */
145
+ export declare function parseUriDirect(value: string): string;
146
+ /**
147
+ * Parse email directly from pre-split line value
148
+ *
149
+ * @param value - The line value (everything after "e=")
150
+ * @returns Email string
151
+ */
152
+ export declare function parseEmailDirect(value: string): string;
153
+ /**
154
+ * Parse phone directly from pre-split line value
155
+ *
156
+ * @param value - The line value (everything after "p=")
157
+ * @returns Phone string
158
+ */
159
+ export declare function parsePhoneDirect(value: string): string;
160
+ /**
161
+ * Parse key directly from pre-split line value
162
+ *
163
+ * @param value - The line value (everything after "k=")
164
+ * @returns Key string
165
+ */
166
+ export declare function parseKeyDirect(value: string): string;
124
167
  //# sourceMappingURL=field-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"field-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/field-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,OAAO,EACL,OAAO,EACP,WAAW,EAMX,WAAW,EACX,GAAG,EACH,KAAK,EACL,KAAK,EACL,GAAG,EAGJ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAmD,MAAM,iBAAiB,CAAC;AA0BjH;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAa3D;AAMD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAmCzD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAenE;AAMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAGnE;AAMD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAEnD;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,KAAK,CAEvD;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,KAAK,CAEvD;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAiBjE;AAyHD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAqB/D;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAGnD"}
1
+ {"version":3,"file":"field-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/field-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,OAAO,EAUR,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACL,OAAO,EAGR,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAmD,MAAM,iBAAiB,CAAC;AAmBjH;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAa3D;AAMD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAmCzD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAe9D;AAMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAG9D;AAMD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEtD;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAExD;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAExD;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAiBjE;AAyHD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAqB/D;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAGtD;AAQD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -15,9 +15,14 @@ exports.parsePhoneField = parsePhoneField;
15
15
  exports.parseConnectionField = parseConnectionField;
16
16
  exports.parseBandwidthField = parseBandwidthField;
17
17
  exports.parseKeyField = parseKeyField;
18
- const primitive_parser_1 = require("./primitive-parser");
18
+ exports.parseSessionNameDirect = parseSessionNameDirect;
19
+ exports.parseInformationDirect = parseInformationDirect;
20
+ exports.parseUriDirect = parseUriDirect;
21
+ exports.parseEmailDirect = parseEmailDirect;
22
+ exports.parsePhoneDirect = parsePhoneDirect;
23
+ exports.parseKeyDirect = parseKeyDirect;
24
+ const core_1 = require("./core");
19
25
  const errors_1 = require("../types/errors");
20
- const primitives_1 = require("../types/primitives");
21
26
  const fields_1 = require("../types/fields");
22
27
  const network_1 = require("../types/network");
23
28
  const address_parser_1 = require("../utils/address-parser");
@@ -36,11 +41,11 @@ const address_parser_2 = require("../utils/address-parser");
36
41
  */
37
42
  function parseVersionField(scanner) {
38
43
  const start = scanner.getPosition();
39
- const version = (0, primitive_parser_1.parseInteger)(scanner);
44
+ const version = (0, core_1.parseInteger)(scanner);
40
45
  if (version !== 0) {
41
46
  throw new errors_1.ParseError(`Unsupported SDP version: ${version} (expected 0)`, start.line, start.column);
42
47
  }
43
- return (0, primitives_1.createVersion)(version);
48
+ return 0;
44
49
  }
45
50
  // ============================================================================
46
51
  // Origin Field Parser (o=)
@@ -57,19 +62,19 @@ function parseVersionField(scanner) {
57
62
  function parseOriginField(scanner) {
58
63
  const start = scanner.getPosition();
59
64
  // Parse username (non-whitespace string)
60
- const username = (0, primitive_parser_1.parseNonWSString)(scanner);
65
+ const username = (0, core_1.parseNonWSString)(scanner);
61
66
  scanner.expectSpace();
62
67
  // Parse session ID (non-whitespace string)
63
- const sessId = (0, primitive_parser_1.parseNonWSString)(scanner);
68
+ const sessId = (0, core_1.parseNonWSString)(scanner);
64
69
  scanner.expectSpace();
65
70
  // Parse session version (non-whitespace string)
66
- const sessVersion = (0, primitive_parser_1.parseNonWSString)(scanner);
71
+ const sessVersion = (0, core_1.parseNonWSString)(scanner);
67
72
  scanner.expectSpace();
68
73
  // Parse network type (token)
69
- const netType = (0, primitive_parser_1.parseToken)(scanner);
74
+ const netType = (0, core_1.parseToken)(scanner);
70
75
  scanner.expectSpace();
71
76
  // Parse address type (token)
72
- const addrType = (0, primitive_parser_1.parseToken)(scanner);
77
+ const addrType = (0, core_1.parseToken)(scanner);
73
78
  scanner.expectSpace();
74
79
  // Parse unicast address (depends on addrType)
75
80
  const unicastAddress = (0, address_parser_1.parseUnicastAddress)(scanner.readUntil(/[\r\n]/), addrType);
@@ -125,7 +130,7 @@ function parseInformationField(scanner) {
125
130
  * @returns URI string
126
131
  */
127
132
  function parseUriField(scanner) {
128
- return (0, primitive_parser_1.parseURI)(scanner);
133
+ return (0, core_1.parseURI)(scanner);
129
134
  }
130
135
  // ============================================================================
131
136
  // Email Field Parser (e=)
@@ -139,7 +144,7 @@ function parseUriField(scanner) {
139
144
  * @returns Email string
140
145
  */
141
146
  function parseEmailField(scanner) {
142
- return (0, primitive_parser_1.parseEmail)(scanner);
147
+ return (0, core_1.parseEmail)(scanner);
143
148
  }
144
149
  // ============================================================================
145
150
  // Phone Field Parser (p=)
@@ -153,7 +158,7 @@ function parseEmailField(scanner) {
153
158
  * @returns Phone string
154
159
  */
155
160
  function parsePhoneField(scanner) {
156
- return (0, primitive_parser_1.parsePhone)(scanner);
161
+ return (0, core_1.parsePhone)(scanner);
157
162
  }
158
163
  // ============================================================================
159
164
  // Connection Field Parser (c=)
@@ -174,10 +179,10 @@ function parsePhoneField(scanner) {
174
179
  function parseConnectionField(scanner) {
175
180
  const start = scanner.getPosition();
176
181
  // Parse network type (token)
177
- const netType = (0, primitive_parser_1.parseToken)(scanner);
182
+ const netType = (0, core_1.parseToken)(scanner);
178
183
  scanner.expectSpace();
179
184
  // Parse address type (token)
180
- const addrType = (0, primitive_parser_1.parseToken)(scanner);
185
+ const addrType = (0, core_1.parseToken)(scanner);
181
186
  scanner.expectSpace();
182
187
  // Parse connection address
183
188
  const connectionAddress = parseConnectionAddress(scanner, addrType);
@@ -212,13 +217,13 @@ function parseConnectionAddress(scanner, addrType) {
212
217
  }
213
218
  // Multicast address - parse TTL and/or number of addresses
214
219
  scanner.advance(); // consume '/'
215
- const firstParam = (0, primitive_parser_1.parseInteger)(scanner);
220
+ const firstParam = (0, core_1.parseInteger)(scanner);
216
221
  let ttl;
217
222
  let numAddresses;
218
223
  // Check for second parameter
219
224
  if (scanner.peek() === '/') {
220
225
  scanner.advance(); // consume second '/'
221
- const secondParam = (0, primitive_parser_1.parseInteger)(scanner);
226
+ const secondParam = (0, core_1.parseInteger)(scanner);
222
227
  // For IPv4: first is TTL, second is numAddresses
223
228
  // For FQDN: first is TTL, second is numAddresses
224
229
  // For IPv6: TTL is forbidden, so first is numAddresses
@@ -252,11 +257,11 @@ function parseConnectionAddress(scanner, addrType) {
252
257
  if (!(0, address_parser_2.isIP4MulticastAddress)(addressPart)) {
253
258
  throw new errors_1.ParseError(`IPv4 address '${addressPart}' with TTL/numAddresses must be a multicast address (224.0.0.0 - 239.255.255.255)`, start.line, start.column);
254
259
  }
255
- return (0, network_1.createIP4MulticastAddress)((0, network_1.createIP4Address)(addressPart), ttl, numAddresses);
260
+ return (0, network_1.createIP4MulticastAddress)(addressPart, ttl, numAddresses);
256
261
  }
257
262
  else {
258
263
  // Assume FQDN - cannot validate multicast range for FQDNs
259
- return (0, network_1.createFQDNMulticastAddress)((0, network_1.createFQDN)(addressPart), ttl, numAddresses);
264
+ return (0, network_1.createFQDNMulticastAddress)(addressPart, ttl, numAddresses);
260
265
  }
261
266
  }
262
267
  else if (addrType === 'IP6') {
@@ -266,16 +271,16 @@ function parseConnectionAddress(scanner, addrType) {
266
271
  if (!(0, address_parser_2.isIP6MulticastAddress)(addressPart)) {
267
272
  throw new errors_1.ParseError(`IPv6 address '${addressPart}' with numAddresses must be a multicast address (must start with FF)`, start.line, start.column);
268
273
  }
269
- return (0, network_1.createIP6MulticastAddress)((0, network_1.createIP6Address)(addressPart), numAddresses);
274
+ return (0, network_1.createIP6MulticastAddress)(addressPart, numAddresses);
270
275
  }
271
276
  else {
272
277
  // Assume FQDN - cannot validate multicast range for FQDNs
273
- return (0, network_1.createFQDNMulticastAddress)((0, network_1.createFQDN)(addressPart), ttl, numAddresses);
278
+ return (0, network_1.createFQDNMulticastAddress)(addressPart, ttl, numAddresses);
274
279
  }
275
280
  }
276
281
  else {
277
282
  // Extension address type
278
- return (0, network_1.createFQDNMulticastAddress)((0, network_1.createFQDN)(addressPart), ttl, numAddresses);
283
+ return (0, network_1.createFQDNMulticastAddress)(addressPart, ttl, numAddresses);
279
284
  }
280
285
  }
281
286
  // ============================================================================
@@ -300,7 +305,7 @@ function parseConnectionAddress(scanner, addrType) {
300
305
  function parseBandwidthField(scanner) {
301
306
  const start = scanner.getPosition();
302
307
  // Parse bandwidth type (token before ':')
303
- const bwtype = (0, primitive_parser_1.parseToken)(scanner);
308
+ const bwtype = (0, core_1.parseToken)(scanner);
304
309
  // Expect ':'
305
310
  const ch = scanner.peek();
306
311
  if (ch !== ':') {
@@ -308,7 +313,7 @@ function parseBandwidthField(scanner) {
308
313
  }
309
314
  scanner.advance();
310
315
  // Parse bandwidth value (integer)
311
- const bandwidth = (0, primitive_parser_1.parseInteger)(scanner);
316
+ const bandwidth = (0, core_1.parseInteger)(scanner);
312
317
  return (0, fields_1.createBandwidth)(bwtype, bandwidth);
313
318
  }
314
319
  // ============================================================================
@@ -333,3 +338,66 @@ function parseKeyField(scanner) {
333
338
  // Read entire line
334
339
  return scanner.readUntil(/[\r\n]/);
335
340
  }
341
+ // ============================================================================
342
+ // Simplified Direct Parsers (no Scanner overhead)
343
+ // ============================================================================
344
+ // These parsers accept already-split line values directly, avoiding Scanner
345
+ // instantiation overhead for trivial fields that just read to end-of-line.
346
+ /**
347
+ * Parse session name directly from pre-split line value
348
+ *
349
+ * @param value - The line value (everything after "s=")
350
+ * @returns SessionName
351
+ * @throws ParseError if empty
352
+ */
353
+ function parseSessionNameDirect(value) {
354
+ if (value.length === 0) {
355
+ throw new errors_1.ParseError('Session name cannot be empty', 1, 1);
356
+ }
357
+ return value;
358
+ }
359
+ /**
360
+ * Parse information directly from pre-split line value
361
+ *
362
+ * @param value - The line value (everything after "i=")
363
+ * @returns Information string
364
+ */
365
+ function parseInformationDirect(value) {
366
+ return value;
367
+ }
368
+ /**
369
+ * Parse URI directly from pre-split line value
370
+ *
371
+ * @param value - The line value (everything after "u=")
372
+ * @returns URI string
373
+ */
374
+ function parseUriDirect(value) {
375
+ return value;
376
+ }
377
+ /**
378
+ * Parse email directly from pre-split line value
379
+ *
380
+ * @param value - The line value (everything after "e=")
381
+ * @returns Email string
382
+ */
383
+ function parseEmailDirect(value) {
384
+ return value;
385
+ }
386
+ /**
387
+ * Parse phone directly from pre-split line value
388
+ *
389
+ * @param value - The line value (everything after "p=")
390
+ * @returns Phone string
391
+ */
392
+ function parsePhoneDirect(value) {
393
+ return value;
394
+ }
395
+ /**
396
+ * Parse key directly from pre-split line value
397
+ *
398
+ * @param value - The line value (everything after "k=")
399
+ * @returns Key string
400
+ */
401
+ function parseKeyDirect(value) {
402
+ return value;
403
+ }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Parses media descriptions (m= and associated fields)
5
5
  */
6
- import { Scanner } from './scanner';
6
+ import { Scanner } from './core';
7
7
  import { Media, MediaDescription } from '../types/media';
8
8
  /**
9
9
  * Parse media field
@@ -1 +1 @@
1
- {"version":3,"file":"media-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/media-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,EACL,KAAK,EACL,gBAAgB,EAMjB,MAAM,gBAAgB,CAAC;AAWxB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,KAAK,CA6FvD;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,iBAAiB,EAAE,OAAO,EAC1B,eAAe,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GACjD,gBAAgB,CAmElB"}
1
+ {"version":3,"file":"media-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/media-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAmC,MAAM,QAAQ,CAAC;AAGlE,OAAO,EACL,KAAK,EACL,gBAAgB,EAMjB,MAAM,gBAAgB,CAAC;AAUxB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,KAAK,CA2FvD;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,iBAAiB,EAAE,OAAO,EAC1B,eAAe,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GACjD,gBAAgB,CAiElB"}
@@ -7,13 +7,10 @@
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.parseMediaField = parseMediaField;
9
9
  exports.parseMediaDescription = parseMediaDescription;
10
- const scanner_1 = require("./scanner");
11
- const primitive_parser_1 = require("./primitive-parser");
10
+ const core_1 = require("./core");
12
11
  const field_parser_1 = require("./field-parser");
13
- const attribute_parser_1 = require("./attribute-parser");
14
12
  const errors_1 = require("../types/errors");
15
13
  const media_1 = require("../types/media");
16
- const primitives_1 = require("../types/primitives");
17
14
  // ============================================================================
18
15
  // Media Field Parser (m=)
19
16
  // ============================================================================
@@ -34,8 +31,7 @@ const primitives_1 = require("../types/primitives");
34
31
  function parseMediaField(scanner) {
35
32
  const start = scanner.getPosition();
36
33
  // Parse media type (token)
37
- const mediaTypeStr = (0, primitive_parser_1.parseToken)(scanner);
38
- const mediaType = (0, primitives_1.createMediaType)(mediaTypeStr);
34
+ const mediaType = (0, core_1.parseToken)(scanner);
39
35
  // Parse port or port range
40
36
  scanner.skipWhitespace();
41
37
  const portStart = scanner.getPosition();
@@ -73,13 +69,12 @@ function parseMediaField(scanner) {
73
69
  if (protoStr.length === 0) {
74
70
  throw new errors_1.ParseError('Expected protocol', protoStart.line, protoStart.column);
75
71
  }
76
- const proto = (0, primitives_1.createProtocol)(protoStr);
72
+ const proto = protoStr;
77
73
  // Parse formats (one or more)
78
74
  const formats = [];
79
75
  scanner.skipWhitespace();
80
76
  while (!scanner.isEOF() && scanner.peek() !== '\r' && scanner.peek() !== '\n') {
81
- const formatStr = (0, primitive_parser_1.parseToken)(scanner);
82
- formats.push((0, primitives_1.createFormat)(formatStr));
77
+ formats.push((0, core_1.parseToken)(scanner));
83
78
  scanner.skipWhitespace();
84
79
  }
85
80
  if (formats.length === 0) {
@@ -118,28 +113,27 @@ function parseMediaDescription(mediaFieldScanner, additionalLines) {
118
113
  let key;
119
114
  const attributes = [];
120
115
  for (const line of additionalLines) {
121
- const scanner = new scanner_1.Scanner(line.value);
122
116
  switch (line.type) {
123
117
  case 'i':
124
118
  if (information !== undefined) {
125
119
  throw new errors_1.ParseError('Duplicate information field in media description', 0, 0);
126
120
  }
127
- information = (0, field_parser_1.parseInformationField)(scanner);
121
+ information = (0, field_parser_1.parseInformationDirect)(line.value);
128
122
  break;
129
123
  case 'c':
130
- connections.push((0, field_parser_1.parseConnectionField)(scanner));
124
+ connections.push((0, field_parser_1.parseConnectionField)(new core_1.Scanner(line.value)));
131
125
  break;
132
126
  case 'b':
133
- bandwidths.push((0, field_parser_1.parseBandwidthField)(scanner));
127
+ bandwidths.push((0, field_parser_1.parseBandwidthField)(new core_1.Scanner(line.value)));
134
128
  break;
135
129
  case 'k':
136
130
  if (key !== undefined) {
137
131
  throw new errors_1.ParseError('Duplicate key field in media description', 0, 0);
138
132
  }
139
- key = (0, field_parser_1.parseKeyField)(scanner);
133
+ key = (0, field_parser_1.parseKeyDirect)(line.value);
140
134
  break;
141
135
  case 'a':
142
- attributes.push((0, attribute_parser_1.parseAttributeField)(scanner));
136
+ attributes.push((0, core_1.parseAttributeField)(new core_1.Scanner(line.value)));
143
137
  break;
144
138
  default:
145
139
  // Unknown field type - this shouldn't happen if called correctly
@@ -1 +1 @@
1
- {"version":3,"file":"session-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/session-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,OAAO,EAAE,kBAAkB,EAA4B,MAAM,kBAAkB,CAAC;AAYhF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAkNzE"}
1
+ {"version":3,"file":"session-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/session-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,OAAO,EAAE,kBAAkB,EAA4B,MAAM,kBAAkB,CAAC;AAYhF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAkNzE"}
@@ -6,10 +6,9 @@
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.parseSessionDescription = parseSessionDescription;
9
- const scanner_1 = require("./scanner");
9
+ const core_1 = require("./core");
10
10
  const field_parser_1 = require("./field-parser");
11
11
  const time_parser_1 = require("./time-parser");
12
- const attribute_parser_1 = require("./attribute-parser");
13
12
  const media_parser_1 = require("./media-parser");
14
13
  const errors_1 = require("../types/errors");
15
14
  const session_1 = require("../types/session");
@@ -75,13 +74,13 @@ function parseSessionDescription(input) {
75
74
  // ========================================================================
76
75
  // v= version (required, exactly one)
77
76
  const vLine = expect('v', 'version');
78
- const version = (0, field_parser_1.parseVersionField)(new scanner_1.Scanner(vLine.value));
77
+ const version = (0, field_parser_1.parseVersionField)(new core_1.Scanner(vLine.value));
79
78
  // o= origin (required, exactly one)
80
79
  const oLine = expect('o', 'origin');
81
- const origin = (0, field_parser_1.parseOriginField)(new scanner_1.Scanner(oLine.value));
80
+ const origin = (0, field_parser_1.parseOriginField)(new core_1.Scanner(oLine.value));
82
81
  // s= session name (required, exactly one)
83
82
  const sLine = expect('s', 'session name');
84
- const sessionName = (0, field_parser_1.parseSessionNameField)(new scanner_1.Scanner(sLine.value));
83
+ const sessionName = (0, field_parser_1.parseSessionNameDirect)(sLine.value);
85
84
  // ========================================================================
86
85
  // 2. Parse optional session-level fields (i=, u=, e=, p=, c=, b=)
87
86
  // ========================================================================
@@ -94,32 +93,32 @@ function parseSessionDescription(input) {
94
93
  // i= session information (optional, at most one)
95
94
  if (((_a = current()) === null || _a === void 0 ? void 0 : _a.type) === 'i') {
96
95
  const iLine = consume();
97
- sessionInformation = (0, field_parser_1.parseInformationField)(new scanner_1.Scanner(iLine.value));
96
+ sessionInformation = (0, field_parser_1.parseInformationDirect)(iLine.value);
98
97
  }
99
98
  // u= URI (optional, at most one)
100
99
  if (((_b = current()) === null || _b === void 0 ? void 0 : _b.type) === 'u') {
101
100
  const uLine = consume();
102
- uri = (0, field_parser_1.parseUriField)(new scanner_1.Scanner(uLine.value));
101
+ uri = (0, field_parser_1.parseUriDirect)(uLine.value);
103
102
  }
104
103
  // e= email (optional, multiple)
105
104
  while (((_c = current()) === null || _c === void 0 ? void 0 : _c.type) === 'e') {
106
105
  const eLine = consume();
107
- emails.push((0, field_parser_1.parseEmailField)(new scanner_1.Scanner(eLine.value)));
106
+ emails.push((0, field_parser_1.parseEmailDirect)(eLine.value));
108
107
  }
109
108
  // p= phone (optional, multiple)
110
109
  while (((_d = current()) === null || _d === void 0 ? void 0 : _d.type) === 'p') {
111
110
  const pLine = consume();
112
- phones.push((0, field_parser_1.parsePhoneField)(new scanner_1.Scanner(pLine.value)));
111
+ phones.push((0, field_parser_1.parsePhoneDirect)(pLine.value));
113
112
  }
114
113
  // c= connection (optional, at most one at session level)
115
114
  if (((_e = current()) === null || _e === void 0 ? void 0 : _e.type) === 'c') {
116
115
  const cLine = consume();
117
- connection = (0, field_parser_1.parseConnectionField)(new scanner_1.Scanner(cLine.value));
116
+ connection = (0, field_parser_1.parseConnectionField)(new core_1.Scanner(cLine.value));
118
117
  }
119
118
  // b= bandwidth (optional, multiple)
120
119
  while (((_f = current()) === null || _f === void 0 ? void 0 : _f.type) === 'b') {
121
120
  const bLine = consume();
122
- bandwidths.push((0, field_parser_1.parseBandwidthField)(new scanner_1.Scanner(bLine.value)));
121
+ bandwidths.push((0, field_parser_1.parseBandwidthField)(new core_1.Scanner(bLine.value)));
123
122
  }
124
123
  // ========================================================================
125
124
  // 3. Parse time descriptions (required, at least one)
@@ -132,18 +131,18 @@ function parseSessionDescription(input) {
132
131
  // Parse time descriptions until we hit k=, a=, m=, or end
133
132
  while (((_k = current()) === null || _k === void 0 ? void 0 : _k.type) === 't') {
134
133
  const tLine = consume();
135
- const timing = (0, time_parser_1.parseTimingField)(new scanner_1.Scanner(tLine.value));
134
+ const timing = (0, time_parser_1.parseTimingField)(new core_1.Scanner(tLine.value));
136
135
  // Parse optional repeat times (r=)
137
136
  const repeats = [];
138
137
  while (((_l = current()) === null || _l === void 0 ? void 0 : _l.type) === 'r') {
139
138
  const rLine = consume();
140
- repeats.push((0, time_parser_1.parseRepeatField)(new scanner_1.Scanner(rLine.value)));
139
+ repeats.push((0, time_parser_1.parseRepeatField)(new core_1.Scanner(rLine.value)));
141
140
  }
142
141
  // Parse optional timezone adjustments (z=)
143
142
  let timezone;
144
143
  if (((_m = current()) === null || _m === void 0 ? void 0 : _m.type) === 'z') {
145
144
  const zLine = consume();
146
- timezone = (0, time_parser_1.parseTimezoneField)(new scanner_1.Scanner(zLine.value));
145
+ timezone = (0, time_parser_1.parseTimezoneField)(new core_1.Scanner(zLine.value));
147
146
  }
148
147
  timeDescriptions.push((0, time_parser_1.parseTimeDescription)(timing, repeats, timezone));
149
148
  }
@@ -155,12 +154,12 @@ function parseSessionDescription(input) {
155
154
  // k= key (optional, at most one)
156
155
  if (((_o = current()) === null || _o === void 0 ? void 0 : _o.type) === 'k') {
157
156
  const kLine = consume();
158
- key = (0, field_parser_1.parseKeyField)(new scanner_1.Scanner(kLine.value));
157
+ key = (0, field_parser_1.parseKeyDirect)(kLine.value);
159
158
  }
160
159
  // a= attributes (optional, multiple)
161
160
  while (((_p = current()) === null || _p === void 0 ? void 0 : _p.type) === 'a') {
162
161
  const aLine = consume();
163
- attributes.push((0, attribute_parser_1.parseAttributeField)(new scanner_1.Scanner(aLine.value)));
162
+ attributes.push((0, core_1.parseAttributeField)(new core_1.Scanner(aLine.value)));
164
163
  }
165
164
  // ========================================================================
166
165
  // 5. Parse media descriptions (optional, zero or more)
@@ -176,7 +175,7 @@ function parseSessionDescription(input) {
176
175
  mediaLines.push({ type: line.type, value: line.value });
177
176
  }
178
177
  // Parse media description
179
- const mediaDescription = (0, media_parser_1.parseMediaDescription)(new scanner_1.Scanner(mLine.value), mediaLines);
178
+ const mediaDescription = (0, media_parser_1.parseMediaDescription)(new core_1.Scanner(mLine.value), mediaLines);
180
179
  mediaDescriptions.push(mediaDescription);
181
180
  }
182
181
  // ========================================================================
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Parsers for time description fields (t=, r=, z=)
5
5
  */
6
- import { Scanner } from './scanner';
6
+ import { Scanner } from './core';
7
7
  import { Timing, Repeat, Timezone, TimeDescription } from '../types/time';
8
8
  /**
9
9
  * Parse timing field
@@ -1 +1 @@
1
- {"version":3,"file":"time-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/time-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,MAAM,EACN,MAAM,EACN,QAAQ,EAER,eAAe,EAMhB,MAAM,eAAe,CAAC;AAOvB;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAsBzD;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CA2CzD;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAgD7D;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAAM,EAAO,EACtB,QAAQ,CAAC,EAAE,QAAQ,GAClB,eAAe,CAEjB"}
1
+ {"version":3,"file":"time-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/time-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAgC,MAAM,QAAQ,CAAC;AAE/D,OAAO,EACL,MAAM,EACN,MAAM,EACN,QAAQ,EAER,eAAe,EAMhB,MAAM,eAAe,CAAC;AAOvB;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAsBzD;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CA2CzD;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAgD7D;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAAM,EAAO,EACtB,QAAQ,CAAC,EAAE,QAAQ,GAClB,eAAe,CAEjB"}
@@ -9,7 +9,7 @@ exports.parseTimingField = parseTimingField;
9
9
  exports.parseRepeatField = parseRepeatField;
10
10
  exports.parseTimezoneField = parseTimezoneField;
11
11
  exports.parseTimeDescription = parseTimeDescription;
12
- const primitive_parser_1 = require("./primitive-parser");
12
+ const core_1 = require("./core");
13
13
  const errors_1 = require("../types/errors");
14
14
  const time_1 = require("../types/time");
15
15
  // ============================================================================
@@ -30,11 +30,11 @@ const time_1 = require("../types/time");
30
30
  function parseTimingField(scanner) {
31
31
  const start = scanner.getPosition();
32
32
  // Parse start time
33
- const startTime = (0, primitive_parser_1.parseNtpTime)(scanner);
33
+ const startTime = (0, core_1.parseNtpTime)(scanner);
34
34
  // Expect space
35
35
  scanner.expectSpace();
36
36
  // Parse stop time
37
- const stopTime = (0, primitive_parser_1.parseNtpTime)(scanner);
37
+ const stopTime = (0, core_1.parseNtpTime)(scanner);
38
38
  // Validate timing constraints
39
39
  try {
40
40
  return (0, time_1.createTiming)(startTime, stopTime);
@@ -67,10 +67,10 @@ function parseTimingField(scanner) {
67
67
  function parseRepeatField(scanner) {
68
68
  const start = scanner.getPosition();
69
69
  // Parse repeat interval
70
- const interval = (0, primitive_parser_1.parseTypedTime)(scanner);
70
+ const interval = (0, core_1.parseTypedTime)(scanner);
71
71
  scanner.expectSpace();
72
72
  // Parse active duration
73
- const duration = (0, primitive_parser_1.parseTypedTime)(scanner);
73
+ const duration = (0, core_1.parseTypedTime)(scanner);
74
74
  // Parse offsets (at least one required)
75
75
  const offsets = [];
76
76
  while (!scanner.isEOF()) {
@@ -79,7 +79,7 @@ function parseRepeatField(scanner) {
79
79
  break;
80
80
  }
81
81
  scanner.expectSpace();
82
- offsets.push((0, primitive_parser_1.parseTypedTime)(scanner));
82
+ offsets.push((0, core_1.parseTypedTime)(scanner));
83
83
  }
84
84
  // Validate at least one offset
85
85
  if (offsets.length === 0) {
@@ -120,10 +120,10 @@ function parseTimezoneField(scanner) {
120
120
  break;
121
121
  }
122
122
  // Parse adjustment time
123
- const time = (0, primitive_parser_1.parseNtpTime)(scanner);
123
+ const time = (0, core_1.parseNtpTime)(scanner);
124
124
  scanner.expectSpace();
125
125
  // Parse offset (can be negative, but parseTypedTime handles the sign in the string)
126
- const offset = (0, primitive_parser_1.parseTypedTime)(scanner);
126
+ const offset = (0, core_1.parseTypedTime)(scanner);
127
127
  adjustments.push((0, time_1.createTimezoneAdjustment)(time, offset));
128
128
  // Check for more adjustments
129
129
  if (!scanner.isEOF()) {