properties-file 2.1.1 → 2.1.4
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 -21
- package/README.md +215 -215
- package/lib/content/index.d.ts +18 -18
- package/lib/content/index.js +61 -61
- package/lib/file/index.d.ts +21 -21
- package/lib/file/index.js +32 -32
- package/lib/index.d.ts +10 -10
- package/lib/index.js +12 -12
- package/lib/loader/webpack.d.ts +8 -8
- package/lib/loader/webpack.js +14 -14
- package/lib/properties-file.d.ts +7 -7
- package/lib/properties.d.ts +55 -55
- package/lib/properties.js +91 -91
- package/lib/property-line.d.ts +22 -22
- package/lib/property-line.js +48 -48
- package/lib/property.d.ts +64 -64
- package/lib/property.js +205 -205
- package/package.json +80 -80
package/lib/property-line.js
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PropertyLine = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Object representing a line from the content of .properties file.
|
|
6
|
-
*/
|
|
7
|
-
var PropertyLine = /** @class */ (function () {
|
|
8
|
-
/**
|
|
9
|
-
* Create a new line object.
|
|
10
|
-
*
|
|
11
|
-
* @param line - The raw content of a line.
|
|
12
|
-
* @param isMultiline - Is the line spreading on multiple lines?
|
|
13
|
-
*/
|
|
14
|
-
function PropertyLine(line, isMultiline) {
|
|
15
|
-
/** True if the line continues, otherwise false. */
|
|
16
|
-
this.continues = false;
|
|
17
|
-
/** True if the line is blank, otherwise false. */
|
|
18
|
-
this.isBlank = false;
|
|
19
|
-
/** True if the line is a comment, otherwise false. */
|
|
20
|
-
this.isComment = false;
|
|
21
|
-
this.content = line.trimStart();
|
|
22
|
-
this.isMultiline = isMultiline;
|
|
23
|
-
if (this.content.length === 0) {
|
|
24
|
-
// Line is blank.
|
|
25
|
-
this.isBlank = true;
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
if (!this.isMultiline) {
|
|
29
|
-
// Line is a comment.
|
|
30
|
-
this.isComment = !!/^[!#]/.test(this.content);
|
|
31
|
-
}
|
|
32
|
-
if (!this.isComment) {
|
|
33
|
-
// Otherwise, check if the line continues on the next line.
|
|
34
|
-
var backslashMatch = this.content.match(/(?<backslashes>\\+)$/);
|
|
35
|
-
if (backslashMatch === null || backslashMatch === void 0 ? void 0 : backslashMatch.groups) {
|
|
36
|
-
// If the number of backslashes is odd, the line continues, otherwise it doesn't.
|
|
37
|
-
this.continues = !!(backslashMatch.groups.backslashes.length % 2);
|
|
38
|
-
if (this.continues) {
|
|
39
|
-
// Remove the trailing slash so that we can concatenate the line with the next one.
|
|
40
|
-
this.content = this.content.slice(0, -1);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return PropertyLine;
|
|
47
|
-
}());
|
|
48
|
-
exports.PropertyLine = PropertyLine;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PropertyLine = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Object representing a line from the content of .properties file.
|
|
6
|
+
*/
|
|
7
|
+
var PropertyLine = /** @class */ (function () {
|
|
8
|
+
/**
|
|
9
|
+
* Create a new line object.
|
|
10
|
+
*
|
|
11
|
+
* @param line - The raw content of a line.
|
|
12
|
+
* @param isMultiline - Is the line spreading on multiple lines?
|
|
13
|
+
*/
|
|
14
|
+
function PropertyLine(line, isMultiline) {
|
|
15
|
+
/** True if the line continues, otherwise false. */
|
|
16
|
+
this.continues = false;
|
|
17
|
+
/** True if the line is blank, otherwise false. */
|
|
18
|
+
this.isBlank = false;
|
|
19
|
+
/** True if the line is a comment, otherwise false. */
|
|
20
|
+
this.isComment = false;
|
|
21
|
+
this.content = line.trimStart();
|
|
22
|
+
this.isMultiline = isMultiline;
|
|
23
|
+
if (this.content.length === 0) {
|
|
24
|
+
// Line is blank.
|
|
25
|
+
this.isBlank = true;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
if (!this.isMultiline) {
|
|
29
|
+
// Line is a comment.
|
|
30
|
+
this.isComment = !!/^[!#]/.test(this.content);
|
|
31
|
+
}
|
|
32
|
+
if (!this.isComment) {
|
|
33
|
+
// Otherwise, check if the line continues on the next line.
|
|
34
|
+
var backslashMatch = this.content.match(/(?<backslashes>\\+)$/);
|
|
35
|
+
if (backslashMatch === null || backslashMatch === void 0 ? void 0 : backslashMatch.groups) {
|
|
36
|
+
// If the number of backslashes is odd, the line continues, otherwise it doesn't.
|
|
37
|
+
this.continues = !!(backslashMatch.groups.backslashes.length % 2);
|
|
38
|
+
if (this.continues) {
|
|
39
|
+
// Remove the trailing slash so that we can concatenate the line with the next one.
|
|
40
|
+
this.content = this.content.slice(0, -1);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return PropertyLine;
|
|
47
|
+
}());
|
|
48
|
+
exports.PropertyLine = PropertyLine;
|
package/lib/property.d.ts
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
import { PropertyLine } from './property-line';
|
|
2
|
-
/**
|
|
3
|
-
* Object representing a property (key/value).
|
|
4
|
-
*/
|
|
5
|
-
export declare class Property {
|
|
6
|
-
/** The length of the delimiter, including its whitespace characters. */
|
|
7
|
-
delimiterLength: number | undefined;
|
|
8
|
-
/** The starting position of the delimiter separating the key from the value. */
|
|
9
|
-
delimiterPosition: number | undefined;
|
|
10
|
-
/** The property key, including its escaped characters. */
|
|
11
|
-
escapedKey: string;
|
|
12
|
-
/** The property value, including its escaped characters. */
|
|
13
|
-
escapedValue: string;
|
|
14
|
-
/** Was the property's key used more than once? */
|
|
15
|
-
hasKeyCollisions: boolean;
|
|
16
|
-
/** The property key (unescaped). */
|
|
17
|
-
key: string;
|
|
18
|
-
/** Starting line numbers of property objects with the same key. */
|
|
19
|
-
keyCollisionLines: number[];
|
|
20
|
-
/** The content of one or multiple lines when applicable. */
|
|
21
|
-
linesContent: string;
|
|
22
|
-
/** Positions of the newline characters if any. */
|
|
23
|
-
newlinePositions: number[];
|
|
24
|
-
/** The line number at which the property starts. */
|
|
25
|
-
startingLineNumber: number;
|
|
26
|
-
/** The property value (unescaped). */
|
|
27
|
-
value: string;
|
|
28
|
-
/** Does the key definition spread across multiple lines? */
|
|
29
|
-
private hasMultilineKey;
|
|
30
|
-
/** Is the key empty? */
|
|
31
|
-
private hasNoKey;
|
|
32
|
-
/** Is the value empty? */
|
|
33
|
-
private hasNoValue;
|
|
34
|
-
/**
|
|
35
|
-
* Create a new property object.
|
|
36
|
-
*
|
|
37
|
-
* @param propertyLine - A property line object.
|
|
38
|
-
* @param startingLineNumber - The line number at which the property starts.
|
|
39
|
-
*/
|
|
40
|
-
constructor(propertyLine: PropertyLine, startingLineNumber: number);
|
|
41
|
-
/**
|
|
42
|
-
* Add the a line to a multiline property object.
|
|
43
|
-
*
|
|
44
|
-
* @param propertyLine - A property line object.
|
|
45
|
-
*/
|
|
46
|
-
addLine(propertyLine: PropertyLine): void;
|
|
47
|
-
/**
|
|
48
|
-
* Set the property's key and value.
|
|
49
|
-
*/
|
|
50
|
-
setKeyAndValue(): void;
|
|
51
|
-
/**
|
|
52
|
-
* Unescape the content from either key or value of a property.
|
|
53
|
-
*
|
|
54
|
-
* @param escapedContent - The content to unescape.
|
|
55
|
-
* @param startingLineNumber - The starting line number of the content being unescaped.
|
|
56
|
-
*
|
|
57
|
-
* @returns The unescaped content.
|
|
58
|
-
*/
|
|
59
|
-
unescape(escapedContent: string, startingLineNumber: number): string;
|
|
60
|
-
/**
|
|
61
|
-
* Find the delimiting characters separating the key from the value.
|
|
62
|
-
*/
|
|
63
|
-
private findDelimiter;
|
|
64
|
-
}
|
|
1
|
+
import { PropertyLine } from './property-line';
|
|
2
|
+
/**
|
|
3
|
+
* Object representing a property (key/value).
|
|
4
|
+
*/
|
|
5
|
+
export declare class Property {
|
|
6
|
+
/** The length of the delimiter, including its whitespace characters. */
|
|
7
|
+
delimiterLength: number | undefined;
|
|
8
|
+
/** The starting position of the delimiter separating the key from the value. */
|
|
9
|
+
delimiterPosition: number | undefined;
|
|
10
|
+
/** The property key, including its escaped characters. */
|
|
11
|
+
escapedKey: string;
|
|
12
|
+
/** The property value, including its escaped characters. */
|
|
13
|
+
escapedValue: string;
|
|
14
|
+
/** Was the property's key used more than once? */
|
|
15
|
+
hasKeyCollisions: boolean;
|
|
16
|
+
/** The property key (unescaped). */
|
|
17
|
+
key: string;
|
|
18
|
+
/** Starting line numbers of property objects with the same key. */
|
|
19
|
+
keyCollisionLines: number[];
|
|
20
|
+
/** The content of one or multiple lines when applicable. */
|
|
21
|
+
linesContent: string;
|
|
22
|
+
/** Positions of the newline characters if any. */
|
|
23
|
+
newlinePositions: number[];
|
|
24
|
+
/** The line number at which the property starts. */
|
|
25
|
+
startingLineNumber: number;
|
|
26
|
+
/** The property value (unescaped). */
|
|
27
|
+
value: string;
|
|
28
|
+
/** Does the key definition spread across multiple lines? */
|
|
29
|
+
private hasMultilineKey;
|
|
30
|
+
/** Is the key empty? */
|
|
31
|
+
private hasNoKey;
|
|
32
|
+
/** Is the value empty? */
|
|
33
|
+
private hasNoValue;
|
|
34
|
+
/**
|
|
35
|
+
* Create a new property object.
|
|
36
|
+
*
|
|
37
|
+
* @param propertyLine - A property line object.
|
|
38
|
+
* @param startingLineNumber - The line number at which the property starts.
|
|
39
|
+
*/
|
|
40
|
+
constructor(propertyLine: PropertyLine, startingLineNumber: number);
|
|
41
|
+
/**
|
|
42
|
+
* Add the a line to a multiline property object.
|
|
43
|
+
*
|
|
44
|
+
* @param propertyLine - A property line object.
|
|
45
|
+
*/
|
|
46
|
+
addLine(propertyLine: PropertyLine): void;
|
|
47
|
+
/**
|
|
48
|
+
* Set the property's key and value.
|
|
49
|
+
*/
|
|
50
|
+
setKeyAndValue(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Unescape the content from either key or value of a property.
|
|
53
|
+
*
|
|
54
|
+
* @param escapedContent - The content to unescape.
|
|
55
|
+
* @param startingLineNumber - The starting line number of the content being unescaped.
|
|
56
|
+
*
|
|
57
|
+
* @returns The unescaped content.
|
|
58
|
+
*/
|
|
59
|
+
unescape(escapedContent: string, startingLineNumber: number): string;
|
|
60
|
+
/**
|
|
61
|
+
* Find the delimiting characters separating the key from the value.
|
|
62
|
+
*/
|
|
63
|
+
private findDelimiter;
|
|
64
|
+
}
|
package/lib/property.js
CHANGED
|
@@ -1,205 +1,205 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Property = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Object representing a property (key/value).
|
|
6
|
-
*/
|
|
7
|
-
var Property = /** @class */ (function () {
|
|
8
|
-
/**
|
|
9
|
-
* Create a new property object.
|
|
10
|
-
*
|
|
11
|
-
* @param propertyLine - A property line object.
|
|
12
|
-
* @param startingLineNumber - The line number at which the property starts.
|
|
13
|
-
*/
|
|
14
|
-
function Property(propertyLine, startingLineNumber) {
|
|
15
|
-
/** The property key, including its escaped characters. */
|
|
16
|
-
this.escapedKey = '';
|
|
17
|
-
/** The property value, including its escaped characters. */
|
|
18
|
-
this.escapedValue = '';
|
|
19
|
-
/** Was the property's key used more than once? */
|
|
20
|
-
this.hasKeyCollisions = false;
|
|
21
|
-
/** The property key (unescaped). */
|
|
22
|
-
this.key = '';
|
|
23
|
-
/** Starting line numbers of property objects with the same key. */
|
|
24
|
-
this.keyCollisionLines = [];
|
|
25
|
-
/** Positions of the newline characters if any. */
|
|
26
|
-
this.newlinePositions = [];
|
|
27
|
-
/** The property value (unescaped). */
|
|
28
|
-
this.value = '';
|
|
29
|
-
/** Does the key definition spread across multiple lines? */
|
|
30
|
-
this.hasMultilineKey = false;
|
|
31
|
-
/** Is the key empty? */
|
|
32
|
-
this.hasNoKey = false;
|
|
33
|
-
/** Is the value empty? */
|
|
34
|
-
this.hasNoValue = false;
|
|
35
|
-
this.linesContent = propertyLine.content;
|
|
36
|
-
this.startingLineNumber = startingLineNumber;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Add the a line to a multiline property object.
|
|
40
|
-
*
|
|
41
|
-
* @param propertyLine - A property line object.
|
|
42
|
-
*/
|
|
43
|
-
Property.prototype.addLine = function (propertyLine) {
|
|
44
|
-
if (this.linesContent.length > 0) {
|
|
45
|
-
this.newlinePositions.push(this.linesContent.length);
|
|
46
|
-
}
|
|
47
|
-
this.linesContent += propertyLine.content;
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Set the property's key and value.
|
|
51
|
-
*/
|
|
52
|
-
Property.prototype.setKeyAndValue = function () {
|
|
53
|
-
this.findDelimiter();
|
|
54
|
-
if (this.delimiterPosition !== undefined && this.delimiterLength !== undefined) {
|
|
55
|
-
// Set key if present.
|
|
56
|
-
if (!this.hasNoKey) {
|
|
57
|
-
this.escapedKey = this.linesContent.slice(0, this.delimiterPosition);
|
|
58
|
-
this.key = this.unescape(this.escapedKey, this.startingLineNumber);
|
|
59
|
-
}
|
|
60
|
-
// Set value if present.
|
|
61
|
-
if (!this.hasNoValue) {
|
|
62
|
-
this.escapedValue = this.linesContent.slice(this.delimiterPosition + this.delimiterLength);
|
|
63
|
-
this.value = this.unescape(this.escapedValue, this.startingLineNumber);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else if (this.hasNoValue) {
|
|
67
|
-
// Set key if present (no delimiter).
|
|
68
|
-
this.escapedKey = this.linesContent;
|
|
69
|
-
this.key = this.unescape(this.escapedKey, this.startingLineNumber);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Unescape the content from either key or value of a property.
|
|
74
|
-
*
|
|
75
|
-
* @param escapedContent - The content to unescape.
|
|
76
|
-
* @param startingLineNumber - The starting line number of the content being unescaped.
|
|
77
|
-
*
|
|
78
|
-
* @returns The unescaped content.
|
|
79
|
-
*/
|
|
80
|
-
Property.prototype.unescape = function (escapedContent, startingLineNumber) {
|
|
81
|
-
var unescapedContent = '';
|
|
82
|
-
for (var character = escapedContent[0], position = 0; position < escapedContent.length; position++, character = escapedContent[position]) {
|
|
83
|
-
if (character === '\\') {
|
|
84
|
-
var nextCharacter = escapedContent[position + 1];
|
|
85
|
-
switch (nextCharacter) {
|
|
86
|
-
case 'f': {
|
|
87
|
-
// Formfeed/
|
|
88
|
-
unescapedContent += '\f';
|
|
89
|
-
position++;
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
case 'n': {
|
|
93
|
-
// Newline.
|
|
94
|
-
unescapedContent += '\n';
|
|
95
|
-
position++;
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
case 'r': {
|
|
99
|
-
// Carriage return.
|
|
100
|
-
unescapedContent += '\r';
|
|
101
|
-
position++;
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
case 't': {
|
|
105
|
-
// Tab.
|
|
106
|
-
unescapedContent += '\t';
|
|
107
|
-
position++;
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
case 'u': {
|
|
111
|
-
// Unicode character.
|
|
112
|
-
var codePoint = escapedContent.slice(position + 2, position + 6);
|
|
113
|
-
if (!/[\da-f]{4}/i.test(codePoint)) {
|
|
114
|
-
// Code point can only be within Unicode's Multilingual Plane (BMP).
|
|
115
|
-
throw new Error("malformed escaped unicode characters '\\u".concat(codePoint, "' in property starting at line ").concat(startingLineNumber));
|
|
116
|
-
}
|
|
117
|
-
unescapedContent += String.fromCodePoint(Number.parseInt(codePoint, 16));
|
|
118
|
-
position += 5;
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
default: {
|
|
122
|
-
// Otherwise the escape character is not required.
|
|
123
|
-
unescapedContent += nextCharacter;
|
|
124
|
-
position++;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
// When there is \, simply add the character.
|
|
130
|
-
unescapedContent += character;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return unescapedContent;
|
|
134
|
-
};
|
|
135
|
-
/**
|
|
136
|
-
* Find the delimiting characters separating the key from the value.
|
|
137
|
-
*/
|
|
138
|
-
Property.prototype.findDelimiter = function () {
|
|
139
|
-
var _a, _b;
|
|
140
|
-
// If the delimiter was already found, skip.
|
|
141
|
-
if (this.hasNoKey || this.hasNoValue || this.delimiterPosition) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
for (var character = this.linesContent[0], position = 0; position < this.linesContent.length; position++, character = this.linesContent[position]) {
|
|
145
|
-
// If the character is not a delimiter, check the next one.
|
|
146
|
-
if (!/[\t\f :=]/.test(character)) {
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
// Check if the delimiter might be escaped.
|
|
150
|
-
var prefix = !position ? '' : this.linesContent.slice(0, position);
|
|
151
|
-
if (prefix.length > 0) {
|
|
152
|
-
var backslashMatch = prefix.match(/(?<backslashes>\\+)$/);
|
|
153
|
-
if (backslashMatch === null || backslashMatch === void 0 ? void 0 : backslashMatch.groups) {
|
|
154
|
-
var delimiterIsEscaped = !!(backslashMatch.groups.backslashes.length % 2);
|
|
155
|
-
if (delimiterIsEscaped) {
|
|
156
|
-
// If the delimiter is escaped, check the next character.
|
|
157
|
-
continue;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
var delimiter = '';
|
|
162
|
-
this.delimiterPosition = position;
|
|
163
|
-
this.hasMultilineKey = !!(this.newlinePositions.length > 0 && this.newlinePositions[0] > position);
|
|
164
|
-
// Check if the delimiter starts with a whitespace.
|
|
165
|
-
var nextContent = this.linesContent.slice(position);
|
|
166
|
-
var leadingWhitespaceMatch = nextContent.match(/^(?<whitespace>\s+)/);
|
|
167
|
-
var leadingWhitespace = ((_a = leadingWhitespaceMatch === null || leadingWhitespaceMatch === void 0 ? void 0 : leadingWhitespaceMatch.groups) === null || _a === void 0 ? void 0 : _a.whitespace) || '';
|
|
168
|
-
// If there is a whitespace, move to the next character.
|
|
169
|
-
if (leadingWhitespace.length > 0) {
|
|
170
|
-
delimiter += leadingWhitespace;
|
|
171
|
-
nextContent = nextContent.slice(leadingWhitespace.length);
|
|
172
|
-
}
|
|
173
|
-
// Check if there is an equal or colon character.
|
|
174
|
-
if (/[:=]/.test(nextContent[0])) {
|
|
175
|
-
delimiter += nextContent[0];
|
|
176
|
-
nextContent = nextContent.slice(1);
|
|
177
|
-
// If an equal or colon character was found, try to get trailing whitespace.
|
|
178
|
-
var trailingWhitespaceMatch = nextContent.match(/^(?<whitespace>\s+)/);
|
|
179
|
-
var trailingWhitespace = ((_b = trailingWhitespaceMatch === null || trailingWhitespaceMatch === void 0 ? void 0 : trailingWhitespaceMatch.groups) === null || _b === void 0 ? void 0 : _b.whitespace) || '';
|
|
180
|
-
delimiter += trailingWhitespace;
|
|
181
|
-
}
|
|
182
|
-
this.delimiterLength = delimiter.length;
|
|
183
|
-
// If the line starts with a delimiter, the property has no key.
|
|
184
|
-
if (!position) {
|
|
185
|
-
this.hasNoKey = true;
|
|
186
|
-
}
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
// If there was no delimiter found, the property has no value.
|
|
190
|
-
if (this.delimiterPosition === undefined) {
|
|
191
|
-
this.hasNoValue = true;
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
// If the delimiter is after the first newline, mark the key as multiline.
|
|
195
|
-
if (this.newlinePositions.length > 0) {
|
|
196
|
-
var firstLinePosition = this.newlinePositions[0];
|
|
197
|
-
if (firstLinePosition > this.delimiterPosition) {
|
|
198
|
-
this.hasMultilineKey = true;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
return Property;
|
|
204
|
-
}());
|
|
205
|
-
exports.Property = Property;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Property = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Object representing a property (key/value).
|
|
6
|
+
*/
|
|
7
|
+
var Property = /** @class */ (function () {
|
|
8
|
+
/**
|
|
9
|
+
* Create a new property object.
|
|
10
|
+
*
|
|
11
|
+
* @param propertyLine - A property line object.
|
|
12
|
+
* @param startingLineNumber - The line number at which the property starts.
|
|
13
|
+
*/
|
|
14
|
+
function Property(propertyLine, startingLineNumber) {
|
|
15
|
+
/** The property key, including its escaped characters. */
|
|
16
|
+
this.escapedKey = '';
|
|
17
|
+
/** The property value, including its escaped characters. */
|
|
18
|
+
this.escapedValue = '';
|
|
19
|
+
/** Was the property's key used more than once? */
|
|
20
|
+
this.hasKeyCollisions = false;
|
|
21
|
+
/** The property key (unescaped). */
|
|
22
|
+
this.key = '';
|
|
23
|
+
/** Starting line numbers of property objects with the same key. */
|
|
24
|
+
this.keyCollisionLines = [];
|
|
25
|
+
/** Positions of the newline characters if any. */
|
|
26
|
+
this.newlinePositions = [];
|
|
27
|
+
/** The property value (unescaped). */
|
|
28
|
+
this.value = '';
|
|
29
|
+
/** Does the key definition spread across multiple lines? */
|
|
30
|
+
this.hasMultilineKey = false;
|
|
31
|
+
/** Is the key empty? */
|
|
32
|
+
this.hasNoKey = false;
|
|
33
|
+
/** Is the value empty? */
|
|
34
|
+
this.hasNoValue = false;
|
|
35
|
+
this.linesContent = propertyLine.content;
|
|
36
|
+
this.startingLineNumber = startingLineNumber;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Add the a line to a multiline property object.
|
|
40
|
+
*
|
|
41
|
+
* @param propertyLine - A property line object.
|
|
42
|
+
*/
|
|
43
|
+
Property.prototype.addLine = function (propertyLine) {
|
|
44
|
+
if (this.linesContent.length > 0) {
|
|
45
|
+
this.newlinePositions.push(this.linesContent.length);
|
|
46
|
+
}
|
|
47
|
+
this.linesContent += propertyLine.content;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Set the property's key and value.
|
|
51
|
+
*/
|
|
52
|
+
Property.prototype.setKeyAndValue = function () {
|
|
53
|
+
this.findDelimiter();
|
|
54
|
+
if (this.delimiterPosition !== undefined && this.delimiterLength !== undefined) {
|
|
55
|
+
// Set key if present.
|
|
56
|
+
if (!this.hasNoKey) {
|
|
57
|
+
this.escapedKey = this.linesContent.slice(0, this.delimiterPosition);
|
|
58
|
+
this.key = this.unescape(this.escapedKey, this.startingLineNumber);
|
|
59
|
+
}
|
|
60
|
+
// Set value if present.
|
|
61
|
+
if (!this.hasNoValue) {
|
|
62
|
+
this.escapedValue = this.linesContent.slice(this.delimiterPosition + this.delimiterLength);
|
|
63
|
+
this.value = this.unescape(this.escapedValue, this.startingLineNumber);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (this.hasNoValue) {
|
|
67
|
+
// Set key if present (no delimiter).
|
|
68
|
+
this.escapedKey = this.linesContent;
|
|
69
|
+
this.key = this.unescape(this.escapedKey, this.startingLineNumber);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Unescape the content from either key or value of a property.
|
|
74
|
+
*
|
|
75
|
+
* @param escapedContent - The content to unescape.
|
|
76
|
+
* @param startingLineNumber - The starting line number of the content being unescaped.
|
|
77
|
+
*
|
|
78
|
+
* @returns The unescaped content.
|
|
79
|
+
*/
|
|
80
|
+
Property.prototype.unescape = function (escapedContent, startingLineNumber) {
|
|
81
|
+
var unescapedContent = '';
|
|
82
|
+
for (var character = escapedContent[0], position = 0; position < escapedContent.length; position++, character = escapedContent[position]) {
|
|
83
|
+
if (character === '\\') {
|
|
84
|
+
var nextCharacter = escapedContent[position + 1];
|
|
85
|
+
switch (nextCharacter) {
|
|
86
|
+
case 'f': {
|
|
87
|
+
// Formfeed/
|
|
88
|
+
unescapedContent += '\f';
|
|
89
|
+
position++;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case 'n': {
|
|
93
|
+
// Newline.
|
|
94
|
+
unescapedContent += '\n';
|
|
95
|
+
position++;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case 'r': {
|
|
99
|
+
// Carriage return.
|
|
100
|
+
unescapedContent += '\r';
|
|
101
|
+
position++;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case 't': {
|
|
105
|
+
// Tab.
|
|
106
|
+
unescapedContent += '\t';
|
|
107
|
+
position++;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 'u': {
|
|
111
|
+
// Unicode character.
|
|
112
|
+
var codePoint = escapedContent.slice(position + 2, position + 6);
|
|
113
|
+
if (!/[\da-f]{4}/i.test(codePoint)) {
|
|
114
|
+
// Code point can only be within Unicode's Multilingual Plane (BMP).
|
|
115
|
+
throw new Error("malformed escaped unicode characters '\\u".concat(codePoint, "' in property starting at line ").concat(startingLineNumber));
|
|
116
|
+
}
|
|
117
|
+
unescapedContent += String.fromCodePoint(Number.parseInt(codePoint, 16));
|
|
118
|
+
position += 5;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
default: {
|
|
122
|
+
// Otherwise the escape character is not required.
|
|
123
|
+
unescapedContent += nextCharacter;
|
|
124
|
+
position++;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// When there is \, simply add the character.
|
|
130
|
+
unescapedContent += character;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return unescapedContent;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Find the delimiting characters separating the key from the value.
|
|
137
|
+
*/
|
|
138
|
+
Property.prototype.findDelimiter = function () {
|
|
139
|
+
var _a, _b;
|
|
140
|
+
// If the delimiter was already found, skip.
|
|
141
|
+
if (this.hasNoKey || this.hasNoValue || this.delimiterPosition) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
for (var character = this.linesContent[0], position = 0; position < this.linesContent.length; position++, character = this.linesContent[position]) {
|
|
145
|
+
// If the character is not a delimiter, check the next one.
|
|
146
|
+
if (!/[\t\f :=]/.test(character)) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
// Check if the delimiter might be escaped.
|
|
150
|
+
var prefix = !position ? '' : this.linesContent.slice(0, position);
|
|
151
|
+
if (prefix.length > 0) {
|
|
152
|
+
var backslashMatch = prefix.match(/(?<backslashes>\\+)$/);
|
|
153
|
+
if (backslashMatch === null || backslashMatch === void 0 ? void 0 : backslashMatch.groups) {
|
|
154
|
+
var delimiterIsEscaped = !!(backslashMatch.groups.backslashes.length % 2);
|
|
155
|
+
if (delimiterIsEscaped) {
|
|
156
|
+
// If the delimiter is escaped, check the next character.
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
var delimiter = '';
|
|
162
|
+
this.delimiterPosition = position;
|
|
163
|
+
this.hasMultilineKey = !!(this.newlinePositions.length > 0 && this.newlinePositions[0] > position);
|
|
164
|
+
// Check if the delimiter starts with a whitespace.
|
|
165
|
+
var nextContent = this.linesContent.slice(position);
|
|
166
|
+
var leadingWhitespaceMatch = nextContent.match(/^(?<whitespace>\s+)/);
|
|
167
|
+
var leadingWhitespace = ((_a = leadingWhitespaceMatch === null || leadingWhitespaceMatch === void 0 ? void 0 : leadingWhitespaceMatch.groups) === null || _a === void 0 ? void 0 : _a.whitespace) || '';
|
|
168
|
+
// If there is a whitespace, move to the next character.
|
|
169
|
+
if (leadingWhitespace.length > 0) {
|
|
170
|
+
delimiter += leadingWhitespace;
|
|
171
|
+
nextContent = nextContent.slice(leadingWhitespace.length);
|
|
172
|
+
}
|
|
173
|
+
// Check if there is an equal or colon character.
|
|
174
|
+
if (/[:=]/.test(nextContent[0])) {
|
|
175
|
+
delimiter += nextContent[0];
|
|
176
|
+
nextContent = nextContent.slice(1);
|
|
177
|
+
// If an equal or colon character was found, try to get trailing whitespace.
|
|
178
|
+
var trailingWhitespaceMatch = nextContent.match(/^(?<whitespace>\s+)/);
|
|
179
|
+
var trailingWhitespace = ((_b = trailingWhitespaceMatch === null || trailingWhitespaceMatch === void 0 ? void 0 : trailingWhitespaceMatch.groups) === null || _b === void 0 ? void 0 : _b.whitespace) || '';
|
|
180
|
+
delimiter += trailingWhitespace;
|
|
181
|
+
}
|
|
182
|
+
this.delimiterLength = delimiter.length;
|
|
183
|
+
// If the line starts with a delimiter, the property has no key.
|
|
184
|
+
if (!position) {
|
|
185
|
+
this.hasNoKey = true;
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
// If there was no delimiter found, the property has no value.
|
|
190
|
+
if (this.delimiterPosition === undefined) {
|
|
191
|
+
this.hasNoValue = true;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// If the delimiter is after the first newline, mark the key as multiline.
|
|
195
|
+
if (this.newlinePositions.length > 0) {
|
|
196
|
+
var firstLinePosition = this.newlinePositions[0];
|
|
197
|
+
if (firstLinePosition > this.delimiterPosition) {
|
|
198
|
+
this.hasMultilineKey = true;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
return Property;
|
|
204
|
+
}());
|
|
205
|
+
exports.Property = Property;
|