@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,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format validators for SDP (RFC 8866)
|
|
3
|
+
*
|
|
4
|
+
* Validates email, phone, and URI formats per RFC 8866 Section 5.5, 5.6 and Section 9 (Grammar)
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Validate email address format per RFC 8866 Section 9
|
|
8
|
+
*
|
|
9
|
+
* email-address = address-and-comment / dispname-and-address / addr-spec
|
|
10
|
+
* address-and-comment = addr-spec 1*SP "(" 1*email-safe ")"
|
|
11
|
+
* dispname-and-address = 1*email-safe 1*SP "<" addr-spec ">"
|
|
12
|
+
*
|
|
13
|
+
* @param input - Email field value
|
|
14
|
+
* @returns true if format is valid
|
|
15
|
+
*/
|
|
16
|
+
export declare function isValidEmailFormat(input: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Parse email components
|
|
19
|
+
*
|
|
20
|
+
* @param input - Email field value
|
|
21
|
+
* @returns Parsed components or null if invalid
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseEmailComponents(input: string): {
|
|
24
|
+
email: string;
|
|
25
|
+
displayName?: string;
|
|
26
|
+
} | null;
|
|
27
|
+
/**
|
|
28
|
+
* Validate phone number format per RFC 8866 Section 9
|
|
29
|
+
*
|
|
30
|
+
* phone-number = phone *SP "(" 1*email-safe ")" /
|
|
31
|
+
* 1*email-safe "<" phone ">" /
|
|
32
|
+
* phone
|
|
33
|
+
*
|
|
34
|
+
* @param input - Phone field value
|
|
35
|
+
* @returns true if format is valid
|
|
36
|
+
*/
|
|
37
|
+
export declare function isValidPhoneFormat(input: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Parse phone components
|
|
40
|
+
*
|
|
41
|
+
* @param input - Phone field value
|
|
42
|
+
* @returns Parsed components or null if invalid
|
|
43
|
+
*/
|
|
44
|
+
export declare function parsePhoneComponents(input: string): {
|
|
45
|
+
phone: string;
|
|
46
|
+
displayName?: string;
|
|
47
|
+
} | null;
|
|
48
|
+
/**
|
|
49
|
+
* Validate URI-reference format per RFC 3986
|
|
50
|
+
*
|
|
51
|
+
* URI-reference = URI / relative-ref
|
|
52
|
+
* URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
|
|
53
|
+
* relative-ref = relative-part [ "?" query ] [ "#" fragment ]
|
|
54
|
+
*
|
|
55
|
+
* This is a simplified validation that checks:
|
|
56
|
+
* 1. All characters are valid URI characters
|
|
57
|
+
* 2. If there's a scheme, it's properly formatted
|
|
58
|
+
* 3. Percent-encoding is valid (% followed by two hex digits)
|
|
59
|
+
* 4. No control characters or spaces
|
|
60
|
+
*
|
|
61
|
+
* @param input - URI field value
|
|
62
|
+
* @returns true if format is valid
|
|
63
|
+
*/
|
|
64
|
+
export declare function isValidURIReference(input: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Parse URI components
|
|
67
|
+
*
|
|
68
|
+
* Extracts scheme and the rest of the URI if present
|
|
69
|
+
*
|
|
70
|
+
* @param input - URI field value
|
|
71
|
+
* @returns Parsed components or null if invalid
|
|
72
|
+
*/
|
|
73
|
+
export declare function parseURIComponents(input: string): {
|
|
74
|
+
scheme?: string;
|
|
75
|
+
rest: string;
|
|
76
|
+
} | null;
|
|
77
|
+
//# sourceMappingURL=format-validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-validators.d.ts","sourceRoot":"","sources":["../../../src/utils/format-validators.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgJH;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAmCzD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,GACZ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkChD;AAiDD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAqBzD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,GACZ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgChD;AAuHD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CA2C1D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuB1C"}
|
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Format validators for SDP (RFC 8866)
|
|
4
|
+
*
|
|
5
|
+
* Validates email, phone, and URI formats per RFC 8866 Section 5.5, 5.6 and Section 9 (Grammar)
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.isValidEmailFormat = isValidEmailFormat;
|
|
9
|
+
exports.parseEmailComponents = parseEmailComponents;
|
|
10
|
+
exports.isValidPhoneFormat = isValidPhoneFormat;
|
|
11
|
+
exports.parsePhoneComponents = parsePhoneComponents;
|
|
12
|
+
exports.isValidURIReference = isValidURIReference;
|
|
13
|
+
exports.parseURIComponents = parseURIComponents;
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Email-safe Character Validation
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Check if a character is email-safe per RFC 8866 Section 9
|
|
19
|
+
*
|
|
20
|
+
* email-safe = %x01-09/%x0B-0C/%x0E-27/%x2A-3B/%x3D/%x3F-FF
|
|
21
|
+
* (any byte except NUL, CR, LF, or the quoting characters ()<>)
|
|
22
|
+
*
|
|
23
|
+
* @param ch - Character to check
|
|
24
|
+
* @returns true if character is email-safe
|
|
25
|
+
*/
|
|
26
|
+
function isEmailSafe(ch) {
|
|
27
|
+
const code = ch.charCodeAt(0);
|
|
28
|
+
return ((code >= 0x01 && code <= 0x09) || // %x01-09
|
|
29
|
+
(code >= 0x0b && code <= 0x0c) || // %x0B-0C
|
|
30
|
+
(code >= 0x0e && code <= 0x27) || // %x0E-27 (includes most printable chars except ()
|
|
31
|
+
(code >= 0x2a && code <= 0x3b) || // %x2A-3B (includes *, +, -, ., digits, :, ;)
|
|
32
|
+
code === 0x3d || // %x3D (=)
|
|
33
|
+
(code >= 0x3f && code <= 0xff) // %x3F-FF (includes ?, @, A-Z, a-z, etc.)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if an entire string is email-safe
|
|
38
|
+
*/
|
|
39
|
+
function isEmailSafeString(str) {
|
|
40
|
+
for (const ch of str) {
|
|
41
|
+
if (!isEmailSafe(ch)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return str.length > 0;
|
|
46
|
+
}
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// ReDoS-safe Format Parsing Helpers
|
|
49
|
+
// ============================================================================
|
|
50
|
+
/**
|
|
51
|
+
* Parse "display <content>" format without regex to avoid ReDoS
|
|
52
|
+
* @param input - String to parse
|
|
53
|
+
* @param requireSpaceBeforeOpen - Whether space is required before <
|
|
54
|
+
* @returns Parsed parts or null if invalid format
|
|
55
|
+
*/
|
|
56
|
+
function parseAngleBracketFormat(input, requireSpaceBeforeOpen) {
|
|
57
|
+
// Must end with >
|
|
58
|
+
if (!input.endsWith('>'))
|
|
59
|
+
return null;
|
|
60
|
+
// Find the last < (in case display name contains <, though it shouldn't)
|
|
61
|
+
const openIdx = input.lastIndexOf('<');
|
|
62
|
+
if (openIdx === -1 || openIdx === 0)
|
|
63
|
+
return null;
|
|
64
|
+
const content = input.substring(openIdx + 1, input.length - 1);
|
|
65
|
+
if (content.length === 0)
|
|
66
|
+
return null;
|
|
67
|
+
const beforeOpen = input.substring(0, openIdx);
|
|
68
|
+
const display = beforeOpen.trimEnd();
|
|
69
|
+
if (display.length === 0)
|
|
70
|
+
return null;
|
|
71
|
+
// Check if there's whitespace before < when required
|
|
72
|
+
if (requireSpaceBeforeOpen) {
|
|
73
|
+
if (beforeOpen.length === display.length) {
|
|
74
|
+
// No trailing whitespace found
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { display, content };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse "content (comment)" format without regex to avoid ReDoS
|
|
82
|
+
* @param input - String to parse
|
|
83
|
+
* @returns Parsed parts or null if invalid format
|
|
84
|
+
*/
|
|
85
|
+
function parseParenthesisFormat(input) {
|
|
86
|
+
// Must end with )
|
|
87
|
+
if (!input.endsWith(')'))
|
|
88
|
+
return null;
|
|
89
|
+
// Find the last (
|
|
90
|
+
const openIdx = input.lastIndexOf('(');
|
|
91
|
+
if (openIdx === -1 || openIdx === 0)
|
|
92
|
+
return null;
|
|
93
|
+
const comment = input.substring(openIdx + 1, input.length - 1);
|
|
94
|
+
if (comment.length === 0)
|
|
95
|
+
return null;
|
|
96
|
+
const content = input.substring(0, openIdx).trimEnd();
|
|
97
|
+
if (content.length === 0)
|
|
98
|
+
return null;
|
|
99
|
+
return { content, comment };
|
|
100
|
+
}
|
|
101
|
+
// ============================================================================
|
|
102
|
+
// Email Format Validation (RFC 8866 Section 5.6, Section 9)
|
|
103
|
+
// ============================================================================
|
|
104
|
+
/**
|
|
105
|
+
* Basic addr-spec validation
|
|
106
|
+
*
|
|
107
|
+
* This is a simplified validation for RFC 5322 addr-spec.
|
|
108
|
+
* Full RFC 5322 addr-spec parsing is complex; this validates the common pattern.
|
|
109
|
+
*
|
|
110
|
+
* @param email - Email address to validate
|
|
111
|
+
* @returns true if appears to be a valid email addr-spec
|
|
112
|
+
*/
|
|
113
|
+
function isValidAddrSpec(email) {
|
|
114
|
+
// Basic pattern: local-part@domain
|
|
115
|
+
// Must have exactly one @ not at start or end
|
|
116
|
+
const atIndex = email.indexOf('@');
|
|
117
|
+
if (atIndex <= 0 || atIndex === email.length - 1) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
// Check no second @
|
|
121
|
+
if (email.indexOf('@', atIndex + 1) !== -1) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const localPart = email.substring(0, atIndex);
|
|
125
|
+
const domain = email.substring(atIndex + 1);
|
|
126
|
+
// Local part and domain must not be empty
|
|
127
|
+
if (localPart.length === 0 || domain.length === 0) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
// Domain must have at least one character and no leading/trailing dots
|
|
131
|
+
if (domain.startsWith('.') || domain.endsWith('.')) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Validate email address format per RFC 8866 Section 9
|
|
138
|
+
*
|
|
139
|
+
* email-address = address-and-comment / dispname-and-address / addr-spec
|
|
140
|
+
* address-and-comment = addr-spec 1*SP "(" 1*email-safe ")"
|
|
141
|
+
* dispname-and-address = 1*email-safe 1*SP "<" addr-spec ">"
|
|
142
|
+
*
|
|
143
|
+
* @param input - Email field value
|
|
144
|
+
* @returns true if format is valid
|
|
145
|
+
*/
|
|
146
|
+
function isValidEmailFormat(input) {
|
|
147
|
+
const trimmed = input.trim();
|
|
148
|
+
if (trimmed.length === 0) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
// Check for dispname-and-address format: Display Name <email@domain>
|
|
152
|
+
// Must have at least one character before the angle brackets (1*email-safe)
|
|
153
|
+
const angleParsed = parseAngleBracketFormat(trimmed, true);
|
|
154
|
+
if (angleParsed) {
|
|
155
|
+
return isEmailSafeString(angleParsed.display) && isValidAddrSpec(angleParsed.content);
|
|
156
|
+
}
|
|
157
|
+
// Reject angle brackets without proper format (e.g., "<email@domain>" without display name)
|
|
158
|
+
if (trimmed.includes('<') || trimmed.includes('>')) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
// Check for address-and-comment format: email@domain (Display Name)
|
|
162
|
+
const parenParsed = parseParenthesisFormat(trimmed);
|
|
163
|
+
if (parenParsed) {
|
|
164
|
+
// Content must not contain whitespace (it's an addr-spec)
|
|
165
|
+
if (/\s/.test(parenParsed.content)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return isValidAddrSpec(parenParsed.content) && isEmailSafeString(parenParsed.comment);
|
|
169
|
+
}
|
|
170
|
+
// Reject unclosed or empty parentheses
|
|
171
|
+
if (trimmed.includes('(') || trimmed.includes(')')) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
// Plain addr-spec format: email@domain
|
|
175
|
+
return isValidAddrSpec(trimmed);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Parse email components
|
|
179
|
+
*
|
|
180
|
+
* @param input - Email field value
|
|
181
|
+
* @returns Parsed components or null if invalid
|
|
182
|
+
*/
|
|
183
|
+
function parseEmailComponents(input) {
|
|
184
|
+
const trimmed = input.trim();
|
|
185
|
+
if (trimmed.length === 0) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
// Check for dispname-and-address format: Display Name <email@domain>
|
|
189
|
+
const angleParsed = parseAngleBracketFormat(trimmed, true);
|
|
190
|
+
if (angleParsed) {
|
|
191
|
+
if (isEmailSafeString(angleParsed.display) && isValidAddrSpec(angleParsed.content)) {
|
|
192
|
+
return { email: angleParsed.content, displayName: angleParsed.display };
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
// Check for address-and-comment format: email@domain (Display Name)
|
|
197
|
+
const parenParsed = parseParenthesisFormat(trimmed);
|
|
198
|
+
if (parenParsed) {
|
|
199
|
+
// Content must not contain whitespace (it's an addr-spec)
|
|
200
|
+
if (/\s/.test(parenParsed.content)) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
if (isValidAddrSpec(parenParsed.content) && isEmailSafeString(parenParsed.comment)) {
|
|
204
|
+
return { email: parenParsed.content, displayName: parenParsed.comment };
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
// Plain addr-spec format: email@domain
|
|
209
|
+
if (isValidAddrSpec(trimmed)) {
|
|
210
|
+
return { email: trimmed };
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
// ============================================================================
|
|
215
|
+
// Phone Format Validation (RFC 8866 Section 5.6, Section 9)
|
|
216
|
+
// ============================================================================
|
|
217
|
+
/**
|
|
218
|
+
* Validate phone number format per RFC 8866 Section 9
|
|
219
|
+
*
|
|
220
|
+
* phone = ["+"] DIGIT 1*(SP / "-" / DIGIT)
|
|
221
|
+
*
|
|
222
|
+
* A phone must:
|
|
223
|
+
* - Optionally start with "+"
|
|
224
|
+
* - Have at least one digit after optional "+"
|
|
225
|
+
* - Contain only digits, spaces, and hyphens after the first digit
|
|
226
|
+
*
|
|
227
|
+
* @param phone - Phone number to validate
|
|
228
|
+
* @returns true if format is valid
|
|
229
|
+
*/
|
|
230
|
+
function isValidPhone(phone) {
|
|
231
|
+
if (phone.length === 0) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
let index = 0;
|
|
235
|
+
// Optional leading "+"
|
|
236
|
+
if (phone[index] === '+') {
|
|
237
|
+
index++;
|
|
238
|
+
}
|
|
239
|
+
// Must have at least one digit
|
|
240
|
+
if (index >= phone.length || !/[0-9]/.test(phone[index])) {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
index++;
|
|
244
|
+
// Rest must be digits, spaces, or hyphens (1*(SP / "-" / DIGIT))
|
|
245
|
+
while (index < phone.length) {
|
|
246
|
+
const ch = phone[index];
|
|
247
|
+
if (ch !== ' ' && ch !== '-' && !/[0-9]/.test(ch)) {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
index++;
|
|
251
|
+
}
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Validate phone number format per RFC 8866 Section 9
|
|
256
|
+
*
|
|
257
|
+
* phone-number = phone *SP "(" 1*email-safe ")" /
|
|
258
|
+
* 1*email-safe "<" phone ">" /
|
|
259
|
+
* phone
|
|
260
|
+
*
|
|
261
|
+
* @param input - Phone field value
|
|
262
|
+
* @returns true if format is valid
|
|
263
|
+
*/
|
|
264
|
+
function isValidPhoneFormat(input) {
|
|
265
|
+
const trimmed = input.trim();
|
|
266
|
+
if (trimmed.length === 0) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
// Check for dispname-and-phone format: Display Name <+1 555 1234>
|
|
270
|
+
// Space before < is optional for phone format
|
|
271
|
+
const angleParsed = parseAngleBracketFormat(trimmed, false);
|
|
272
|
+
if (angleParsed) {
|
|
273
|
+
return isEmailSafeString(angleParsed.display) && isValidPhone(angleParsed.content.trim());
|
|
274
|
+
}
|
|
275
|
+
// Check for phone-and-comment format: +1 555 1234 (Display Name)
|
|
276
|
+
const parenParsed = parseParenthesisFormat(trimmed);
|
|
277
|
+
if (parenParsed) {
|
|
278
|
+
return isValidPhone(parenParsed.content) && isEmailSafeString(parenParsed.comment);
|
|
279
|
+
}
|
|
280
|
+
// Plain phone format: +1 555 1234
|
|
281
|
+
return isValidPhone(trimmed);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Parse phone components
|
|
285
|
+
*
|
|
286
|
+
* @param input - Phone field value
|
|
287
|
+
* @returns Parsed components or null if invalid
|
|
288
|
+
*/
|
|
289
|
+
function parsePhoneComponents(input) {
|
|
290
|
+
const trimmed = input.trim();
|
|
291
|
+
if (trimmed.length === 0) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
// Check for dispname-and-phone format: Display Name <+1 555 1234>
|
|
295
|
+
// Space before < is optional for phone format
|
|
296
|
+
const angleParsed = parseAngleBracketFormat(trimmed, false);
|
|
297
|
+
if (angleParsed) {
|
|
298
|
+
const phone = angleParsed.content.trim();
|
|
299
|
+
if (isEmailSafeString(angleParsed.display) && isValidPhone(phone)) {
|
|
300
|
+
return { phone, displayName: angleParsed.display };
|
|
301
|
+
}
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
// Check for phone-and-comment format: +1 555 1234 (Display Name)
|
|
305
|
+
const parenParsed = parseParenthesisFormat(trimmed);
|
|
306
|
+
if (parenParsed) {
|
|
307
|
+
if (isValidPhone(parenParsed.content) && isEmailSafeString(parenParsed.comment)) {
|
|
308
|
+
return { phone: parenParsed.content, displayName: parenParsed.comment };
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
// Plain phone format: +1 555 1234
|
|
313
|
+
if (isValidPhone(trimmed)) {
|
|
314
|
+
return { phone: trimmed };
|
|
315
|
+
}
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
// ============================================================================
|
|
319
|
+
// URI Format Validation (RFC 8866 Section 5.5, RFC 3986)
|
|
320
|
+
// ============================================================================
|
|
321
|
+
/**
|
|
322
|
+
* Check if a character is valid in a URI per RFC 3986
|
|
323
|
+
*
|
|
324
|
+
* Valid URI characters include:
|
|
325
|
+
* - unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
326
|
+
* - reserved = gen-delims / sub-delims
|
|
327
|
+
* - gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
|
328
|
+
* - sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
|
329
|
+
* - pct-encoded = "%" HEXDIG HEXDIG
|
|
330
|
+
*
|
|
331
|
+
* @param ch - Character to check
|
|
332
|
+
* @returns true if character is valid in a URI
|
|
333
|
+
*/
|
|
334
|
+
function isURIChar(ch) {
|
|
335
|
+
const code = ch.charCodeAt(0);
|
|
336
|
+
// ALPHA (A-Z, a-z)
|
|
337
|
+
if ((code >= 0x41 && code <= 0x5a) || (code >= 0x61 && code <= 0x7a)) {
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
// DIGIT (0-9)
|
|
341
|
+
if (code >= 0x30 && code <= 0x39) {
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
// unreserved: - . _ ~
|
|
345
|
+
if (ch === '-' || ch === '.' || ch === '_' || ch === '~') {
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
// gen-delims: : / ? # [ ] @
|
|
349
|
+
if (ch === ':' || ch === '/' || ch === '?' || ch === '#' || ch === '[' || ch === ']' || ch === '@') {
|
|
350
|
+
return true;
|
|
351
|
+
}
|
|
352
|
+
// sub-delims: ! $ & ' ( ) * + , ; =
|
|
353
|
+
if (ch === '!' || ch === '$' || ch === '&' || ch === "'" || ch === '(' || ch === ')' ||
|
|
354
|
+
ch === '*' || ch === '+' || ch === ',' || ch === ';' || ch === '=') {
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
// percent-encoding marker
|
|
358
|
+
if (ch === '%') {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Check if a string is a valid URI scheme per RFC 3986
|
|
365
|
+
*
|
|
366
|
+
* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
|
367
|
+
*
|
|
368
|
+
* @param scheme - Potential scheme string
|
|
369
|
+
* @returns true if valid scheme
|
|
370
|
+
*/
|
|
371
|
+
function isValidScheme(scheme) {
|
|
372
|
+
if (scheme.length === 0) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
// First character must be ALPHA
|
|
376
|
+
const firstCode = scheme.charCodeAt(0);
|
|
377
|
+
if (!((firstCode >= 0x41 && firstCode <= 0x5a) || (firstCode >= 0x61 && firstCode <= 0x7a))) {
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
// Rest must be ALPHA / DIGIT / "+" / "-" / "."
|
|
381
|
+
for (let i = 1; i < scheme.length; i++) {
|
|
382
|
+
const code = scheme.charCodeAt(i);
|
|
383
|
+
const ch = scheme[i];
|
|
384
|
+
if (!((code >= 0x41 && code <= 0x5a) || // A-Z
|
|
385
|
+
(code >= 0x61 && code <= 0x7a) || // a-z
|
|
386
|
+
(code >= 0x30 && code <= 0x39) || // 0-9
|
|
387
|
+
ch === '+' || ch === '-' || ch === '.')) {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Validate percent-encoding in a URI
|
|
395
|
+
*
|
|
396
|
+
* Checks that all % characters are followed by exactly two hex digits
|
|
397
|
+
*
|
|
398
|
+
* @param uri - URI string to check
|
|
399
|
+
* @returns true if all percent-encoding is valid
|
|
400
|
+
*/
|
|
401
|
+
function hasValidPercentEncoding(uri) {
|
|
402
|
+
let i = 0;
|
|
403
|
+
while (i < uri.length) {
|
|
404
|
+
if (uri[i] === '%') {
|
|
405
|
+
// Must be followed by exactly two hex digits
|
|
406
|
+
if (i + 2 >= uri.length) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
const hex1 = uri[i + 1];
|
|
410
|
+
const hex2 = uri[i + 2];
|
|
411
|
+
if (!/[0-9A-Fa-f]/.test(hex1) || !/[0-9A-Fa-f]/.test(hex2)) {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
i += 3;
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
i++;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return true;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Validate URI-reference format per RFC 3986
|
|
424
|
+
*
|
|
425
|
+
* URI-reference = URI / relative-ref
|
|
426
|
+
* URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
|
|
427
|
+
* relative-ref = relative-part [ "?" query ] [ "#" fragment ]
|
|
428
|
+
*
|
|
429
|
+
* This is a simplified validation that checks:
|
|
430
|
+
* 1. All characters are valid URI characters
|
|
431
|
+
* 2. If there's a scheme, it's properly formatted
|
|
432
|
+
* 3. Percent-encoding is valid (% followed by two hex digits)
|
|
433
|
+
* 4. No control characters or spaces
|
|
434
|
+
*
|
|
435
|
+
* @param input - URI field value
|
|
436
|
+
* @returns true if format is valid
|
|
437
|
+
*/
|
|
438
|
+
function isValidURIReference(input) {
|
|
439
|
+
const trimmed = input.trim();
|
|
440
|
+
if (trimmed.length === 0) {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
// Check for control characters or spaces (not allowed)
|
|
444
|
+
for (const ch of trimmed) {
|
|
445
|
+
const code = ch.charCodeAt(0);
|
|
446
|
+
if (code <= 0x20 || code === 0x7f) {
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// Check all characters are valid URI characters
|
|
451
|
+
for (const ch of trimmed) {
|
|
452
|
+
if (!isURIChar(ch)) {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
// Check percent-encoding is valid
|
|
457
|
+
if (!hasValidPercentEncoding(trimmed)) {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
// Check if there's a scheme (look for first ":")
|
|
461
|
+
const colonIndex = trimmed.indexOf(':');
|
|
462
|
+
if (colonIndex > 0) {
|
|
463
|
+
// Potential scheme - validate it
|
|
464
|
+
const potentialScheme = trimmed.substring(0, colonIndex);
|
|
465
|
+
// If the potential scheme contains / or @ or ?, it's not a scheme
|
|
466
|
+
// (it's part of a relative reference like //host or path/to/file)
|
|
467
|
+
if (!potentialScheme.includes('/') && !potentialScheme.includes('@') && !potentialScheme.includes('?')) {
|
|
468
|
+
// This looks like a scheme, validate it
|
|
469
|
+
if (!isValidScheme(potentialScheme)) {
|
|
470
|
+
return false;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Parse URI components
|
|
478
|
+
*
|
|
479
|
+
* Extracts scheme and the rest of the URI if present
|
|
480
|
+
*
|
|
481
|
+
* @param input - URI field value
|
|
482
|
+
* @returns Parsed components or null if invalid
|
|
483
|
+
*/
|
|
484
|
+
function parseURIComponents(input) {
|
|
485
|
+
if (!isValidURIReference(input)) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
const trimmed = input.trim();
|
|
489
|
+
// Check if there's a scheme
|
|
490
|
+
const colonIndex = trimmed.indexOf(':');
|
|
491
|
+
if (colonIndex > 0) {
|
|
492
|
+
const potentialScheme = trimmed.substring(0, colonIndex);
|
|
493
|
+
if (!potentialScheme.includes('/') && !potentialScheme.includes('@') && !potentialScheme.includes('?')) {
|
|
494
|
+
if (isValidScheme(potentialScheme)) {
|
|
495
|
+
return {
|
|
496
|
+
scheme: potentialScheme,
|
|
497
|
+
rest: trimmed.substring(colonIndex + 1),
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// Relative reference (no scheme)
|
|
503
|
+
return { rest: trimmed };
|
|
504
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Line reading utilities for SDP (RFC 8866)
|
|
3
|
+
*
|
|
4
|
+
* RFC 8866 specifies CRLF as the standard line terminator, but parsers
|
|
5
|
+
* SHOULD accept LF alone for robustness. This module handles all three
|
|
6
|
+
* cases: CRLF, LF, and CR.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Parsed line structure
|
|
10
|
+
*/
|
|
11
|
+
export interface ParsedLine {
|
|
12
|
+
/** Line type (single character before '=') */
|
|
13
|
+
readonly type: string;
|
|
14
|
+
/** Line value (everything after '=') */
|
|
15
|
+
readonly value: string;
|
|
16
|
+
/** Original line number (1-indexed) */
|
|
17
|
+
readonly lineNumber: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Split input text into lines, handling CRLF, LF, and CR
|
|
21
|
+
*
|
|
22
|
+
* RFC 8866 Section 5: Text fields use UTF-8 encoding, line ending is CRLF,
|
|
23
|
+
* but parsers SHOULD accept LF alone for compatibility.
|
|
24
|
+
*
|
|
25
|
+
* @param input - Raw SDP text
|
|
26
|
+
* @returns Array of lines (line endings removed)
|
|
27
|
+
*/
|
|
28
|
+
export declare function splitLines(input: string): string[];
|
|
29
|
+
/**
|
|
30
|
+
* Parse a single SDP line into type and value
|
|
31
|
+
*
|
|
32
|
+
* SDP line format: <type>=<value>
|
|
33
|
+
* where <type> is a single character
|
|
34
|
+
*
|
|
35
|
+
* @param line - Single SDP line
|
|
36
|
+
* @returns Parsed line with type and value, or null if invalid
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseLine(line: string): {
|
|
39
|
+
type: string;
|
|
40
|
+
value: string;
|
|
41
|
+
} | null;
|
|
42
|
+
/**
|
|
43
|
+
* Parse all lines in SDP input into structured format
|
|
44
|
+
*
|
|
45
|
+
* @param input - Raw SDP text
|
|
46
|
+
* @returns Array of parsed lines (skips empty/invalid lines)
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseLines(input: string): ParsedLine[];
|
|
49
|
+
/**
|
|
50
|
+
* Join lines back into SDP text format with CRLF line endings
|
|
51
|
+
*
|
|
52
|
+
* Always outputs standard CRLF line endings per RFC 8866,
|
|
53
|
+
* even if input used LF or CR.
|
|
54
|
+
*
|
|
55
|
+
* @param lines - Array of line strings (without line endings)
|
|
56
|
+
* @returns SDP text with CRLF line endings
|
|
57
|
+
*/
|
|
58
|
+
export declare function joinLines(lines: string[]): string;
|
|
59
|
+
/**
|
|
60
|
+
* Format a line in SDP format: <type>=<value>
|
|
61
|
+
*
|
|
62
|
+
* @param type - Single character line type
|
|
63
|
+
* @param value - Line value
|
|
64
|
+
* @returns Formatted SDP line (without line ending)
|
|
65
|
+
*/
|
|
66
|
+
export declare function formatLine(type: string, value: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Validate that a line type is a valid SDP field
|
|
69
|
+
*
|
|
70
|
+
* Valid SDP field types per RFC 8866:
|
|
71
|
+
* v, o, s, i, u, e, p, c, b, t, r, z, k, a, m
|
|
72
|
+
*
|
|
73
|
+
* @param type - Line type character
|
|
74
|
+
* @returns true if valid SDP field type
|
|
75
|
+
*/
|
|
76
|
+
export declare function isValidLineType(type: string): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Get display name for a line type
|
|
79
|
+
*
|
|
80
|
+
* @param type - Line type character
|
|
81
|
+
* @returns Human-readable field name
|
|
82
|
+
*/
|
|
83
|
+
export declare function getLineTypeName(type: string): string;
|
|
84
|
+
//# sourceMappingURL=line-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-reader.d.ts","sourceRoot":"","sources":["../../../src/utils/line-reader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoB9E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAiBtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEjD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoBpD"}
|