properties-file 4.0.0 → 5.0.1

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 (57) hide show
  1. package/README.md +94 -97
  2. package/dist/cjs/bundler/bun.js +1 -1
  3. package/dist/cjs/bundler/esbuild.js +1 -1
  4. package/dist/cjs/bundler/rollup.js +1 -1
  5. package/dist/cjs/bundler/webpack.js +1 -1
  6. package/dist/cjs/editor/index.d.ts +100 -93
  7. package/dist/cjs/editor/index.js +1 -1
  8. package/dist/cjs/escape/index.js +1 -1
  9. package/dist/cjs/index.d.ts +0 -1
  10. package/dist/cjs/index.js +1 -1
  11. package/dist/cjs/package.json +1 -1
  12. package/dist/cjs/parse-properties.d.ts +22 -0
  13. package/dist/cjs/parse-properties.js +1 -0
  14. package/dist/cjs/parser/index.d.ts +3 -0
  15. package/dist/cjs/parser/index.js +1 -0
  16. package/dist/cjs/parser/nodes.d.ts +156 -0
  17. package/dist/cjs/parser/nodes.js +1 -0
  18. package/dist/cjs/parser/normalize.d.ts +12 -0
  19. package/dist/cjs/parser/normalize.js +1 -0
  20. package/dist/cjs/parser/parse.d.ts +23 -0
  21. package/dist/cjs/parser/parse.js +1 -0
  22. package/dist/cjs/parser/properties.d.ts +93 -0
  23. package/dist/cjs/parser/properties.js +1 -0
  24. package/dist/cjs/unescape/index.d.ts +4 -0
  25. package/dist/cjs/unescape/index.js +1 -1
  26. package/dist/esm/editor/index.d.ts +100 -93
  27. package/dist/esm/editor/index.js +1 -1
  28. package/dist/esm/escape/index.js +1 -1
  29. package/dist/esm/index.d.ts +0 -1
  30. package/dist/esm/index.js +1 -1
  31. package/dist/esm/parse-properties.d.ts +22 -0
  32. package/dist/esm/parse-properties.js +1 -0
  33. package/dist/esm/parser/index.d.ts +3 -0
  34. package/dist/esm/parser/index.js +1 -0
  35. package/dist/esm/parser/nodes.d.ts +156 -0
  36. package/dist/esm/parser/nodes.js +1 -0
  37. package/dist/esm/parser/normalize.d.ts +12 -0
  38. package/dist/esm/parser/normalize.js +1 -0
  39. package/dist/esm/parser/parse.d.ts +23 -0
  40. package/dist/esm/parser/parse.js +1 -0
  41. package/dist/esm/parser/properties.d.ts +93 -0
  42. package/dist/esm/parser/properties.js +1 -0
  43. package/dist/esm/unescape/index.d.ts +4 -0
  44. package/dist/esm/unescape/index.js +1 -1
  45. package/package.json +33 -21
  46. package/dist/cjs/properties.d.ts +0 -96
  47. package/dist/cjs/properties.js +0 -1
  48. package/dist/cjs/property-line.d.ts +0 -22
  49. package/dist/cjs/property-line.js +0 -1
  50. package/dist/cjs/property.d.ts +0 -81
  51. package/dist/cjs/property.js +0 -1
  52. package/dist/esm/properties.d.ts +0 -96
  53. package/dist/esm/properties.js +0 -1
  54. package/dist/esm/property-line.d.ts +0 -22
  55. package/dist/esm/property-line.js +0 -1
  56. package/dist/esm/property.d.ts +0 -81
  57. package/dist/esm/property.js +0 -1
@@ -0,0 +1,93 @@
1
+ import type { BlankLineNode, CommentNode, KeyCollisions, KeyValuePairObject, NormalizeOptions, PropertiesNode, PropertyNode } from './nodes.js';
2
+ /**
3
+ * A lossless, ordered representation of a `.properties` file.
4
+ *
5
+ * Every element in the file — properties, comments, and blank lines — is
6
+ * preserved in order. Duplicate keys are all retained. The original content
7
+ * can be reconstructed exactly via {@link format}.
8
+ */
9
+ export declare class Properties {
10
+ /** Whether the content started with a BOM character. */
11
+ readonly hasBom: boolean;
12
+ /** The end-of-line character detected from the content. */
13
+ readonly eolCharacter: string;
14
+ /** All nodes in file order. */
15
+ readonly nodes: PropertiesNode[];
16
+ /**
17
+ * Parse a `.properties` file into a lossless node structure.
18
+ *
19
+ * @param content - The content of a `.properties` file (string or Buffer).
20
+ */
21
+ constructor(content: string | Buffer);
22
+ /**
23
+ * Get all property nodes in file order (including duplicates).
24
+ *
25
+ * @returns An array of all {@link PropertyNode} instances.
26
+ */
27
+ getProperties(): PropertyNode[];
28
+ /**
29
+ * Get all comment nodes in file order.
30
+ *
31
+ * @returns An array of all {@link CommentNode} instances.
32
+ */
33
+ getComments(): CommentNode[];
34
+ /**
35
+ * Get all blank line nodes in file order.
36
+ *
37
+ * @returns An array of all {@link BlankLineNode} instances.
38
+ */
39
+ getBlankLines(): BlankLineNode[];
40
+ /**
41
+ * Get the effective key-value map (last-wins semantics for duplicate keys).
42
+ *
43
+ * @returns A plain object where each key maps to its last-occurring value.
44
+ */
45
+ toObject(): KeyValuePairObject;
46
+ /**
47
+ * Get all property nodes for a given key (all occurrences, in file order).
48
+ *
49
+ * @param key - The unescaped key to search for.
50
+ *
51
+ * @returns An array of matching {@link PropertyNode} instances (empty if not found).
52
+ */
53
+ getPropertyNodes(key: string): PropertyNode[];
54
+ /**
55
+ * Get the effective property node for a given key (last occurrence).
56
+ *
57
+ * @param key - The unescaped key to search for.
58
+ *
59
+ * @returns The last {@link PropertyNode} with this key, or `undefined`.
60
+ */
61
+ getEffectiveProperty(key: string): PropertyNode | undefined;
62
+ /**
63
+ * Get keys that appear more than once, with all their property nodes.
64
+ *
65
+ * @returns An array of {@link KeyCollisions} for duplicate keys.
66
+ */
67
+ getKeyCollisions(): KeyCollisions[];
68
+ /**
69
+ * Get comment and blank line nodes immediately preceding a property.
70
+ *
71
+ * Walks backward from the last occurrence of the given key, collecting
72
+ * comment and blank line nodes until reaching another property or the
73
+ * start of the file.
74
+ *
75
+ * @param key - The unescaped key to find leading nodes for.
76
+ *
77
+ * @returns An array of preceding {@link CommentNode} and {@link BlankLineNode} instances.
78
+ */
79
+ getLeadingNodes(key: string): (CommentNode | BlankLineNode)[];
80
+ /**
81
+ * Format the `.properties` content as a string.
82
+ *
83
+ * Without options, produces an exact lossless reconstruction of the original
84
+ * content. With options, produces normalized output — standardize separators,
85
+ * remove comments, deduplicate keys, and more.
86
+ *
87
+ * @param options - Optional normalization options. When omitted, the output
88
+ * is a lossless round-trip of the original content.
89
+ *
90
+ * @returns The formatted `.properties` file content.
91
+ */
92
+ format(options?: NormalizeOptions): string;
93
+ }
@@ -0,0 +1 @@
1
+ function _class_call_check(e,r){if(!(e instanceof r))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var n=r[t];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _create_class(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),e}import{formatNormalized as formatNormalizedImpl}from"./normalize.js";import{parseDocument}from"./parse.js";var BOM="\ufeff";export var Properties=function(){"use strict";function e(r){_class_call_check(this,e);var t=parseDocument(r);this.hasBom=t.hasBom,this.eolCharacter=t.eolCharacter,this.nodes=t.nodes}return _create_class(e,[{key:"getProperties",value:function(){return this.nodes.filter(function(e){return"property"===e.type})}},{key:"getComments",value:function(){return this.nodes.filter(function(e){return"comment"===e.type})}},{key:"getBlankLines",value:function(){return this.nodes.filter(function(e){return"blank"===e.type})}},{key:"toObject",value:function(){var e={},r=!0,t=!1,n=void 0;try{for(var o,a=this.nodes[Symbol.iterator]();!(r=(o=a.next()).done);r=!0){var i=o.value;"property"===i.type&&(e[i.key]=i.value)}}catch(e){t=!0,n=e}finally{try{r||null==a.return||a.return()}finally{if(t)throw n}}return e}},{key:"getPropertyNodes",value:function(e){return this.nodes.filter(function(r){return"property"===r.type&&r.key===e})}},{key:"getEffectiveProperty",value:function(e){for(var r=this.nodes.length-1;r>=0;r--){var t=this.nodes[r];if("property"===t.type&&t.key===e)return t}}},{key:"getKeyCollisions",value:function(){var e={},r=!0,t=!1,n=void 0;try{for(var o,a=this.nodes[Symbol.iterator]();!(r=(o=a.next()).done);r=!0){var i=o.value;"property"===i.type&&(e[i.key]||(e[i.key]=[]),e[i.key].push(i))}}catch(e){t=!0,n=e}finally{try{r||null==a.return||a.return()}finally{if(t)throw n}}var l=[],s=!0,u=!1,f=void 0;try{for(var y,c=Object.keys(e)[Symbol.iterator]();!(s=(y=c.next()).done);s=!0){var h=y.value;e[h].length>1&&l.push({key:h,nodes:e[h]})}}catch(e){u=!0,f=e}finally{try{s||null==c.return||c.return()}finally{if(u)throw f}}return l}},{key:"getLeadingNodes",value:function(e){for(var r=-1,t=this.nodes.length-1;t>=0;t--){var n=this.nodes[t];if("property"===n.type&&n.key===e){r=t;break}}if(r<=0)return[];for(var o=[],a=r-1;a>=0;a--){var i=this.nodes[a];if("property"===i.type)break;o.unshift(i)}return o}},{key:"format",value:function(e){if(!e){var r=this.eolCharacter,t=[],n=!0,o=!1,a=void 0;try{for(var i,l=this.nodes[Symbol.iterator]();!(n=(i=l.next()).done);n=!0){var s=i.value;"property"===s.type?t.push(s.rawLines.join(r)):t.push(s.rawLine)}}catch(e){o=!0,a=e}finally{try{n||null==l.return||l.return()}finally{if(o)throw a}}return(this.hasBom?BOM:"")+t.join(r)}return formatNormalizedImpl(this.nodes,this.hasBom,this.eolCharacter,e)}}]),e}();
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * Tries to unescape the content from either key or value of a property.
3
3
  *
4
+ * Uses a single-pass, segment-based approach with `charCodeAt()` instead of
5
+ * regex. Scans for backslashes, flushes literal text in bulk via `slice()`,
6
+ * and only builds new characters for actual escape sequences.
7
+ *
4
8
  * @param content - The content to unescape.
5
9
  *
6
10
  * @returns The unescaped content.
@@ -1 +1 @@
1
- var REGEX_INVALID_UNICODE_ESCAPE=/\\u(?![0-9a-fA-F]{4})/,REGEX_ESCAPE=/\\(?:([fnrt])|u([0-9a-fA-F]{4})|(.))/g,ESCAPE_MAP={f:"\f",n:"\n",r:"\r",t:"\t"};export var unescapeContent=function(r){var E;if(-1===r.indexOf("\\"))return r;var n=r.match(REGEX_INVALID_UNICODE_ESCAPE);if(n){var e=null!==(E=n.index)&&void 0!==E?E:0,a=r.slice(e,e+6);throw new Error("malformed escaped unicode characters '".concat(a,"'"))}return r.replace(REGEX_ESCAPE,function(r,E,n,e){return E?ESCAPE_MAP[E]:n?String.fromCharCode(parseInt(n,16)):null!=e?e:""})};
1
+ var CH_BACKSLASH=92,CH_LOWER_F=102,CH_LOWER_N=110,CH_LOWER_R=114,CH_LOWER_T=116,CH_LOWER_U=117,isHexDigit=function(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102},hexValue=function(e){return e>=48&&e<=57?e-48:e>=65&&e<=70?e-55:e-87};export var unescapeContent=function(e){if(-1===e.indexOf("\\"))return e;for(var r=e.length,a="",t=0,c=0;c<r;)if(e.charCodeAt(c)===CH_BACKSLASH){if(c>t&&(a+=e.slice(t,c)),++c>=r){a+="\\",t=c;break}switch(e.charCodeAt(c)){case CH_LOWER_N:a+="\n",c++;break;case CH_LOWER_T:a+="\t",c++;break;case CH_LOWER_R:a+="\r",c++;break;case CH_LOWER_F:a+="\f",c++;break;case CH_LOWER_U:if(c+4>=r||!isHexDigit(e.charCodeAt(c+1))||!isHexDigit(e.charCodeAt(c+2))||!isHexDigit(e.charCodeAt(c+3))||!isHexDigit(e.charCodeAt(c+4))){var i=e.slice(c-1,c+5);throw new Error("malformed escaped unicode characters '".concat(i,"'"))}var C=hexValue(e.charCodeAt(c+1))<<12|hexValue(e.charCodeAt(c+2))<<8|hexValue(e.charCodeAt(c+3))<<4|hexValue(e.charCodeAt(c+4));a+=String.fromCharCode(C),c+=5;break;default:a+=e.charAt(c),c++}t=c}else c++;return t<r&&(a+=e.slice(t,r)),a};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "properties-file",
3
- "version": "4.0.0",
3
+ "version": "5.0.1",
4
4
  "description": ".properties file parser, editor, formatter and bundler integrations.",
5
5
  "keywords": [
6
6
  ".properties",
@@ -99,6 +99,16 @@
99
99
  "default": "./dist/cjs/escape/index.js"
100
100
  }
101
101
  },
102
+ "./parser": {
103
+ "import": {
104
+ "types": "./dist/esm/parser/index.d.ts",
105
+ "default": "./dist/esm/parser/index.js"
106
+ },
107
+ "require": {
108
+ "types": "./dist/cjs/parser/index.d.ts",
109
+ "default": "./dist/cjs/parser/index.js"
110
+ }
111
+ },
102
112
  "./unescape": {
103
113
  "import": {
104
114
  "types": "./dist/esm/unescape/index.d.ts",
@@ -117,54 +127,56 @@
117
127
  "dist"
118
128
  ],
119
129
  "scripts": {
120
- "add-file-type-declaration": "node ./dist/esm/add-import-type.js && find ./dist -name 'add-import-type.*' -type f -delete",
121
- "benchmark": "npx tsx benchmarks/run.ts",
122
- "benchmark-compare": "npx tsx benchmarks/compare.ts",
123
- "build": "npm run check-nvm-node-version && npm run prettier-write && npm run eslint-fix && rm -Rf ./dist && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && echo '{ \"type\": \"commonjs\" }' > dist/cjs/package.json && tsc -p src/build-scripts/tsconfig.json && node dist/build-scripts/build.js && npm run test",
130
+ "benchmark": "npx tsx performance/benchmarks/compare.ts",
131
+ "build": "npm run check-nvm-node-version && npm run prettier-write && npm run eslint-fix && rm -Rf ./dist && tsc && npx tsx src/build-scripts/build.ts && npm run test && npm run size",
124
132
  "check-nvm-node-version": "check-node-version --node $(node -p \"'>='+require('fs').readFileSync('.nvmrc','utf-8').trim()\")",
125
133
  "depcheck": "depcheck",
126
134
  "eslint-fix": "eslint --fix",
127
135
  "ncu": "npm-check-updates",
128
136
  "ncu-update": "npm-check-updates -u",
137
+ "performance-clean": "rm -rf performance/published-packages/.cache performance/benchmarks/.results performance/size/.results",
129
138
  "prepare": "husky",
130
139
  "prettier-write": "prettier --write .",
131
140
  "release": "dotenv -- release-it --only-version",
132
- "test": "jest --coverage"
141
+ "size": "npx tsx performance/size/compare.ts",
142
+ "snapshot": "npx tsx performance/snapshots/manage.ts",
143
+ "test": "jest --coverage",
144
+ "test-node-compat": "docker build --platform linux/amd64 -f tests/node-compat/Dockerfile ."
133
145
  },
134
146
  "devDependencies": {
135
147
  "@release-it/conventional-changelog": "10.0.6",
136
- "@types/bun": "1.3.11",
148
+ "@swc/core": "1.15.24",
149
+ "@types/bun": "1.3.12",
137
150
  "@types/jest": "30.0.0",
138
- "@types/node": "25.5.0",
151
+ "@types/node": "25.6.0",
139
152
  "check-node-version": "4.2.1",
140
153
  "depcheck": "1.4.7",
141
154
  "dotenv-cli": "11.0.0",
142
- "esbuild": "0.27.4",
143
- "eslint": "10.1.0",
155
+ "esbuild": "0.28.0",
156
+ "eslint": "10.2.0",
144
157
  "eslint-config-prettier": "10.1.8",
145
158
  "eslint-import-resolver-typescript": "4.4.4",
146
159
  "eslint-plugin-es-x": "9.6.0",
147
160
  "eslint-plugin-import-x": "4.16.2",
148
- "eslint-plugin-jest": "29.15.0",
149
- "eslint-plugin-package-json": "0.91.0",
161
+ "eslint-plugin-jest": "29.15.2",
162
+ "eslint-plugin-package-json": "0.91.1",
150
163
  "eslint-plugin-prefer-arrow-functions": "3.9.1",
151
164
  "eslint-plugin-prettier": "5.5.5",
152
165
  "eslint-plugin-tsdoc": "0.5.2",
153
- "eslint-plugin-unicorn": "63.0.0",
166
+ "eslint-plugin-unicorn": "64.0.0",
154
167
  "husky": "9.1.7",
155
168
  "jest": "30.3.0",
156
169
  "jiti": "2.6.1",
157
170
  "jsonc-eslint-parser": "3.1.0",
158
- "npm-check-updates": "19.6.5",
159
- "prettier": "3.8.1",
160
- "prettier-plugin-organize-imports": "4.3.0",
161
- "release-it": "19.2.4",
162
- "rollup": "4.60.0",
171
+ "npm-check-updates": "20.0.1",
172
+ "prettier": "3.8.2",
173
+ "release-it": "20.0.0-1",
174
+ "rollup": "4.60.1",
163
175
  "terser": "5.46.1",
164
176
  "tinybench": "6.0.0",
165
- "ts-jest": "29.4.6",
166
- "typescript": "5.9.3",
167
- "typescript-eslint": "8.57.1"
177
+ "ts-jest": "29.4.9",
178
+ "typescript": "6.0.2",
179
+ "typescript-eslint": "8.58.1"
168
180
  },
169
181
  "engines": {
170
182
  "node": "*"
@@ -1,96 +0,0 @@
1
- import { KeyValuePairObject } from '.';
2
- import { Property } from './property';
3
- /**
4
- * Byte-order mark.
5
- */
6
- export declare const BOM = "\uFEFF";
7
- export declare const BOM_CODE_POINT: number;
8
- /** Matches a newline, optionally preceded by a carriage return. */
9
- export declare const REGEX_NEWLINE: RegExp;
10
- /** The default end of line character. */
11
- export declare const DEFAULT_END_OF_LINE_CHARACTER = "\n";
12
- /**
13
- * Get the first end of line (EOL) character from multiline content.
14
- *
15
- * @param content - The content of a `.properties` file.
16
- *
17
- * @returns The multiline content's first end of line (EOL) character.
18
- */
19
- export declare const getFirstEolCharacter: (content: string) => string | undefined;
20
- /**
21
- * A class representing the content of a .properties file.
22
- */
23
- export declare class Properties {
24
- /** Does the .properties content starts with a BOM character? */
25
- readonly hasBom: boolean;
26
- /** The end of line character. */
27
- readonly eolCharacter: string;
28
- /** `.properties` content split by line. */
29
- protected lines: string[];
30
- /** The collection of property object. */
31
- collection: Property[];
32
- /** Object associating keys with their starting line numbers. */
33
- keyLineNumbers: KeyLineNumbers;
34
- /**
35
- * Create `Properties` object.
36
- *
37
- * @param content - The content of a `.properties` file.
38
- */
39
- constructor(content: string | Buffer);
40
- /**
41
- * Parse the `.properties` content line by line.
42
- */
43
- protected parseLines(): void;
44
- /**
45
- * Add a property object into a properties object collection.
46
- *
47
- * @param property - A property object, or undefined.
48
- *
49
- * @returns Undefined so that we conveniently overwrite the property object.
50
- */
51
- private addToCollection;
52
- /**
53
- * Get keys that have collisions (more than one occurrence).
54
- */
55
- getKeyCollisions(): KeyCollisions[];
56
- /**
57
- * Get the key/value object representing the properties.
58
- *
59
- * @returns A key/value object representing the properties.
60
- */
61
- toObject(): KeyValuePairObject;
62
- /**
63
- * Format the object in `.properties`.
64
- *
65
- * @param endOfLineCharacter - The character used for end of lines.
66
- *
67
- * @returns The object in `.properties` format.
68
- */
69
- format(endOfLineCharacter?: '\n' | '\r\n'): string;
70
- }
71
- /**
72
- * Object associating keys with their line numbers.
73
- */
74
- export type KeyLineNumbers = {
75
- [key: string]: number[];
76
- };
77
- /**
78
- * A class representing key within a .properties file that had collisions (more than one occurrence).
79
- */
80
- export declare class KeyCollisions {
81
- /** The key with collisions. */
82
- key: string;
83
- /** The starting line numbers where collisions are found. */
84
- startingLineNumbers: number[];
85
- /**
86
- * Create a new key collision object.
87
- *
88
- * @param key - The key with collisions.
89
- * @param startingLineNumbers - The starting line numbers where collisions are found.
90
- */
91
- constructor(key: string, startingLineNumbers: number[]);
92
- /**
93
- * Get the number of the line from which the value will be used.
94
- */
95
- getApplicableLineNumber(): number | undefined;
96
- }
@@ -1 +0,0 @@
1
- "use strict";var __values=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,r=t&&e[t],i=0;if(r)return r.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&i>=e.length&&(e=void 0),{value:e&&e[i++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")};Object.defineProperty(exports,"__esModule",{value:!0}),exports.KeyCollisions=exports.Properties=exports.getFirstEolCharacter=exports.DEFAULT_END_OF_LINE_CHARACTER=exports.REGEX_NEWLINE=exports.BOM_CODE_POINT=exports.BOM=void 0;var property_1=require("./property"),property_line_1=require("./property-line");exports.BOM="\ufeff",exports.BOM_CODE_POINT=exports.BOM.charCodeAt(0),exports.REGEX_NEWLINE=/\r?\n/,exports.DEFAULT_END_OF_LINE_CHARACTER="\n";var getFirstEolCharacter=function(e){var t=e.indexOf("\n");return-1===t?void 0:"".concat("\r"===e[t-1]?"\r":"","\n")};exports.getFirstEolCharacter=getFirstEolCharacter;var Properties=function(){function e(e){var t;this.collection=[],this.keyLineNumbers={};var r="string"==typeof e?e:e.toString();this.hasBom=r.charCodeAt(0)===exports.BOM_CODE_POINT,this.eolCharacter=null!==(t=(0,exports.getFirstEolCharacter)(r))&&void 0!==t?t:exports.DEFAULT_END_OF_LINE_CHARACTER,this.lines=(this.hasBom?r.slice(1):r).split(exports.REGEX_NEWLINE),this.parseLines()}return e.prototype.parseLines=function(){var e,t;this.collection=[],this.keyLineNumbers={};var r,i,o=0;try{for(var n=__values(this.lines),s=n.next();!s.done;s=n.next()){var l=s.value;o++;var a=new property_line_1.PropertyLine(l,!!r);if(r){if(r.addLine(a),a.isContinuing)continue}else{if(a.isComment||a.isBlank)continue;if(r=new property_1.Property(a,o,i),a.isContinuing)continue}this.addToCollection(r),i=r,r=void 0}}catch(t){e={error:t}}finally{try{s&&!s.done&&(t=n.return)&&t.call(n)}finally{if(e)throw e.error}}},e.prototype.addToCollection=function(e){var t;e.setKeyAndValue(),(null===(t=this.keyLineNumbers[e.key])||void 0===t?void 0:t.length)?(this.keyLineNumbers[e.key].push(e.startingLineNumber),e.hasKeyCollisions=!0,e.keyCollisionLines=this.keyLineNumbers[e.key],this.collection=this.collection.filter(function(t){return t.key!==e.key})):this.keyLineNumbers[e.key]=[e.startingLineNumber],this.collection.push(e)},e.prototype.getKeyCollisions=function(){var e,t,r=[],i=Object.keys(this.keyLineNumbers);try{for(var o=__values(i),n=o.next();!n.done;n=o.next()){var s=n.value,l=this.keyLineNumbers[s];l.length>1&&r.push(new KeyCollisions(s,l))}}catch(t){e={error:t}}finally{try{n&&!n.done&&(t=o.return)&&t.call(o)}finally{if(e)throw e.error}}return r},e.prototype.toObject=function(){var e={};return this.collection.forEach(function(t){e[t.key]=t.value}),e},e.prototype.format=function(e){return"".concat(this.hasBom?exports.BOM:"").concat(this.lines.join(e||this.eolCharacter))},e}();exports.Properties=Properties;var KeyCollisions=function(){function e(e,t){this.key=e,this.startingLineNumbers=t}return e.prototype.getApplicableLineNumber=function(){return this.startingLineNumbers.slice(-1)[0]},e}();exports.KeyCollisions=KeyCollisions;
@@ -1,22 +0,0 @@
1
- /**
2
- * Object representing a line from the content of .properties file.
3
- */
4
- export declare class PropertyLine {
5
- /** The line content, minus the trailing `\` that identifies that the line is continuing. */
6
- content: string;
7
- /** True if the line is continuing to the next line, otherwise false. */
8
- isContinuing: boolean;
9
- /** True if the line is blank, otherwise false. */
10
- isBlank: boolean;
11
- /** True if the line is a comment, otherwise false. */
12
- isComment: boolean;
13
- /** Is the line object a continuation from a previous line? */
14
- isMultiline: boolean;
15
- /**
16
- * Create a new line object.
17
- *
18
- * @param line - The raw content of a line.
19
- * @param isMultiline - Is the line spreading on multiple lines?
20
- */
21
- constructor(line: string, isMultiline: boolean);
22
- }
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.PropertyLine=void 0;var REGEX_LEADING_WHITESPACE=/^\s+/,REGEX_COMMENT=/^[!#]/,REGEX_TRAILING_BACKSLASHES=/(\\+)$/,PropertyLine=function(t,i){if(this.isContinuing=!1,this.isBlank=!1,this.isComment=!1,this.content=t.replace(REGEX_LEADING_WHITESPACE,""),this.isMultiline=i,0===this.content.length)this.isBlank=!0;else if(this.isMultiline||(this.isComment=REGEX_COMMENT.test(this.content)),!this.isComment){var e=this.content.match(REGEX_TRAILING_BACKSLASHES);e&&(this.isContinuing=e[1].length%2==1,this.isContinuing&&(this.content=this.content.slice(0,-1)))}};exports.PropertyLine=PropertyLine;
@@ -1,81 +0,0 @@
1
- import { PropertyLine } from './property-line';
2
- /**
3
- * Object representing a property (key/value).
4
- */
5
- export declare class Property {
6
- /** The content of one or multiple lines when applicable. */
7
- linesContent: string;
8
- /** The property key (unescaped). */
9
- key: string;
10
- /** The property key, including its escaped characters. */
11
- escapedKey: string;
12
- /** Is the key empty? */
13
- private hasNoKey;
14
- /** Does the key definition spread across multiple lines? */
15
- private hasMultilineKey;
16
- /** Starting line numbers of property objects with the same key. */
17
- keyCollisionLines: number[];
18
- /** Was the property's key used more than once? */
19
- hasKeyCollisions: boolean;
20
- /** The key/value pair separator */
21
- separator: string | undefined;
22
- /** The length of the key/value pair separator, including its whitespace characters. */
23
- separatorLength: number | undefined;
24
- /** The starting position of the key/value pair separator. */
25
- separatorPosition: number | undefined;
26
- /** The property value (unescaped). */
27
- value: string;
28
- /** The starting position of the value. */
29
- valuePosition: number | undefined;
30
- /** The property value, including its escaped characters. */
31
- escapedValue: string;
32
- /** Positions of the newline characters if any. */
33
- newlinePositions: number[];
34
- /** The line number at which the property starts. */
35
- readonly startingLineNumber: number;
36
- /** The line number at which the property ends. */
37
- endingLineNumber: number;
38
- /** The previous property object if it exists. */
39
- readonly previousProperty?: Property;
40
- /** The next property object if it exists. */
41
- nextProperty?: Property;
42
- /**
43
- * Create a new property object.
44
- *
45
- * @param propertyLine - A property line object.
46
- * @param startingLineNumber - The line number at which the property starts.
47
- */
48
- constructor(propertyLine: PropertyLine, startingLineNumber: number, previousProperty?: Property);
49
- /**
50
- * Set the next property object.
51
- *
52
- * @param property - The next property object
53
- */
54
- setNextProperty(property: Property): void;
55
- /**
56
- * Add the a line to a multiline property object.
57
- *
58
- * @param propertyLine - A property line object.
59
- */
60
- addLine(propertyLine: PropertyLine): void;
61
- /**
62
- * Set the property's key and value.
63
- */
64
- setKeyAndValue(): void;
65
- /**
66
- * Unescape the content from either key or value of a property.
67
- *
68
- * @param escapedContent - The content to unescape.
69
- * @param startingLineNumber - The starting line number of the content being unescaped.
70
- *
71
- * @returns The unescaped content.
72
- *
73
- * @throws {@link Error}
74
- * This exception is thrown if malformed escaped unicode characters are present.
75
- */
76
- private unescapeLine;
77
- /**
78
- * Find the character separating the key from the value.
79
- */
80
- private findSeparator;
81
- }
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Property=void 0;var unescape_1=require("./unescape"),REGEX_TRAILING_BACKSLASHES=/(\\+)$/,REGEX_LEADING_WHITESPACE=/^([\t\n\v\f\r ]+)/,REGEX_SEPARATOR=/[\t\f :=]/g,REGEX_COLON_OR_EQUALS=/[:=]/,Property=function(){function t(t,e,i){this.key="",this.escapedKey="",this.hasNoKey=!1,this.hasMultilineKey=!1,this.keyCollisionLines=[],this.hasKeyCollisions=!1,this.value="",this.escapedValue="",this.newlinePositions=[],this.linesContent=t.content,this.startingLineNumber=e,this.endingLineNumber=e,this.previousProperty=i,null==i||i.setNextProperty(this)}return t.prototype.setNextProperty=function(t){this.nextProperty=t},t.prototype.addLine=function(t){this.linesContent.length>0&&(this.newlinePositions.push(this.linesContent.length),this.endingLineNumber++),this.linesContent+=t.content},t.prototype.setKeyAndValue=function(){this.findSeparator(),void 0!==this.separatorPosition&&void 0!==this.separatorLength?(this.hasNoKey||(this.escapedKey=this.linesContent.slice(0,this.separatorPosition),this.key=this.unescapeLine(this.escapedKey,this.startingLineNumber)),this.escapedValue=this.linesContent.slice(this.separatorPosition+this.separatorLength),this.value=this.unescapeLine(this.escapedValue,this.startingLineNumber)):(this.escapedKey=this.linesContent,this.key=this.unescapeLine(this.escapedKey,this.startingLineNumber))},t.prototype.unescapeLine=function(t,e){try{return(0,unescape_1.unescapeContent)(t)}catch(t){throw new Error("".concat(t.message," in property starting at line ").concat(e))}},t.prototype.findSeparator=function(){var t,e,i,s;if(!this.hasNoKey&&!this.separator){var n;for(REGEX_SEPARATOR.lastIndex=0;null!==(n=REGEX_SEPARATOR.exec(this.linesContent));){var o=n.index,r=this.linesContent.slice(0,o).match(REGEX_TRAILING_BACKSLASHES);if(r)if(r[1].length%2==1)continue;var h="";this.separatorPosition=o;var a=this.linesContent.slice(o),l=null!==(e=null===(t=a.match(REGEX_LEADING_WHITESPACE))||void 0===t?void 0:t[0])&&void 0!==e?e:"";l.length>0&&(h+=l,a=a.slice(l.length)),REGEX_COLON_OR_EQUALS.test(a[0])&&(h+=a[0],h+=null!==(s=null===(i=(a=a.slice(1)).match(REGEX_LEADING_WHITESPACE))||void 0===i?void 0:i[0])&&void 0!==s?s:""),this.separatorLength=h.length,this.valuePosition=this.separatorPosition+this.separatorLength,this.separator=this.linesContent.slice(this.separatorPosition,this.separatorPosition+this.separatorLength),o||(this.hasNoKey=!0);break}void 0!==this.separatorPosition&&this.newlinePositions.length>0&&this.newlinePositions[0]<this.separatorPosition&&(this.hasMultilineKey=!0)}},t}();exports.Property=Property;
@@ -1,96 +0,0 @@
1
- import { KeyValuePairObject } from './index.js';
2
- import { Property } from './property.js';
3
- /**
4
- * Byte-order mark.
5
- */
6
- export declare const BOM = "\uFEFF";
7
- export declare const BOM_CODE_POINT: number;
8
- /** Matches a newline, optionally preceded by a carriage return. */
9
- export declare const REGEX_NEWLINE: RegExp;
10
- /** The default end of line character. */
11
- export declare const DEFAULT_END_OF_LINE_CHARACTER = "\n";
12
- /**
13
- * Get the first end of line (EOL) character from multiline content.
14
- *
15
- * @param content - The content of a `.properties` file.
16
- *
17
- * @returns The multiline content's first end of line (EOL) character.
18
- */
19
- export declare const getFirstEolCharacter: (content: string) => string | undefined;
20
- /**
21
- * A class representing the content of a .properties file.
22
- */
23
- export declare class Properties {
24
- /** Does the .properties content starts with a BOM character? */
25
- readonly hasBom: boolean;
26
- /** The end of line character. */
27
- readonly eolCharacter: string;
28
- /** `.properties` content split by line. */
29
- protected lines: string[];
30
- /** The collection of property object. */
31
- collection: Property[];
32
- /** Object associating keys with their starting line numbers. */
33
- keyLineNumbers: KeyLineNumbers;
34
- /**
35
- * Create `Properties` object.
36
- *
37
- * @param content - The content of a `.properties` file.
38
- */
39
- constructor(content: string | Buffer);
40
- /**
41
- * Parse the `.properties` content line by line.
42
- */
43
- protected parseLines(): void;
44
- /**
45
- * Add a property object into a properties object collection.
46
- *
47
- * @param property - A property object, or undefined.
48
- *
49
- * @returns Undefined so that we conveniently overwrite the property object.
50
- */
51
- private addToCollection;
52
- /**
53
- * Get keys that have collisions (more than one occurrence).
54
- */
55
- getKeyCollisions(): KeyCollisions[];
56
- /**
57
- * Get the key/value object representing the properties.
58
- *
59
- * @returns A key/value object representing the properties.
60
- */
61
- toObject(): KeyValuePairObject;
62
- /**
63
- * Format the object in `.properties`.
64
- *
65
- * @param endOfLineCharacter - The character used for end of lines.
66
- *
67
- * @returns The object in `.properties` format.
68
- */
69
- format(endOfLineCharacter?: '\n' | '\r\n'): string;
70
- }
71
- /**
72
- * Object associating keys with their line numbers.
73
- */
74
- export type KeyLineNumbers = {
75
- [key: string]: number[];
76
- };
77
- /**
78
- * A class representing key within a .properties file that had collisions (more than one occurrence).
79
- */
80
- export declare class KeyCollisions {
81
- /** The key with collisions. */
82
- key: string;
83
- /** The starting line numbers where collisions are found. */
84
- startingLineNumbers: number[];
85
- /**
86
- * Create a new key collision object.
87
- *
88
- * @param key - The key with collisions.
89
- * @param startingLineNumbers - The starting line numbers where collisions are found.
90
- */
91
- constructor(key: string, startingLineNumbers: number[]);
92
- /**
93
- * Get the number of the line from which the value will be used.
94
- */
95
- getApplicableLineNumber(): number | undefined;
96
- }
@@ -1 +0,0 @@
1
- var __values=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,r=t&&e[t],i=0;if(r)return r.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&i>=e.length&&(e=void 0),{value:e&&e[i++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")};import{Property}from"./property.js";import{PropertyLine}from"./property-line.js";export var BOM="\ufeff";export var BOM_CODE_POINT=BOM.charCodeAt(0);export var REGEX_NEWLINE=/\r?\n/;export var DEFAULT_END_OF_LINE_CHARACTER="\n";export var getFirstEolCharacter=function(e){var t=e.indexOf("\n");return-1===t?void 0:"".concat("\r"===e[t-1]?"\r":"","\n")};var Properties=function(){function e(e){var t;this.collection=[],this.keyLineNumbers={};var r="string"==typeof e?e:e.toString();this.hasBom=r.charCodeAt(0)===BOM_CODE_POINT,this.eolCharacter=null!==(t=getFirstEolCharacter(r))&&void 0!==t?t:DEFAULT_END_OF_LINE_CHARACTER,this.lines=(this.hasBom?r.slice(1):r).split(REGEX_NEWLINE),this.parseLines()}return e.prototype.parseLines=function(){var e,t;this.collection=[],this.keyLineNumbers={};var r,i,n=0;try{for(var o=__values(this.lines),s=o.next();!s.done;s=o.next()){var l=s.value;n++;var a=new PropertyLine(l,!!r);if(r){if(r.addLine(a),a.isContinuing)continue}else{if(a.isComment||a.isBlank)continue;if(r=new Property(a,n,i),a.isContinuing)continue}this.addToCollection(r),i=r,r=void 0}}catch(t){e={error:t}}finally{try{s&&!s.done&&(t=o.return)&&t.call(o)}finally{if(e)throw e.error}}},e.prototype.addToCollection=function(e){var t;e.setKeyAndValue(),(null===(t=this.keyLineNumbers[e.key])||void 0===t?void 0:t.length)?(this.keyLineNumbers[e.key].push(e.startingLineNumber),e.hasKeyCollisions=!0,e.keyCollisionLines=this.keyLineNumbers[e.key],this.collection=this.collection.filter(function(t){return t.key!==e.key})):this.keyLineNumbers[e.key]=[e.startingLineNumber],this.collection.push(e)},e.prototype.getKeyCollisions=function(){var e,t,r=[],i=Object.keys(this.keyLineNumbers);try{for(var n=__values(i),o=n.next();!o.done;o=n.next()){var s=o.value,l=this.keyLineNumbers[s];l.length>1&&r.push(new KeyCollisions(s,l))}}catch(t){e={error:t}}finally{try{o&&!o.done&&(t=n.return)&&t.call(n)}finally{if(e)throw e.error}}return r},e.prototype.toObject=function(){var e={};return this.collection.forEach(function(t){e[t.key]=t.value}),e},e.prototype.format=function(e){return"".concat(this.hasBom?BOM:"").concat(this.lines.join(e||this.eolCharacter))},e}();export{Properties};var KeyCollisions=function(){function e(e,t){this.key=e,this.startingLineNumbers=t}return e.prototype.getApplicableLineNumber=function(){return this.startingLineNumbers.slice(-1)[0]},e}();export{KeyCollisions};
@@ -1,22 +0,0 @@
1
- /**
2
- * Object representing a line from the content of .properties file.
3
- */
4
- export declare class PropertyLine {
5
- /** The line content, minus the trailing `\` that identifies that the line is continuing. */
6
- content: string;
7
- /** True if the line is continuing to the next line, otherwise false. */
8
- isContinuing: boolean;
9
- /** True if the line is blank, otherwise false. */
10
- isBlank: boolean;
11
- /** True if the line is a comment, otherwise false. */
12
- isComment: boolean;
13
- /** Is the line object a continuation from a previous line? */
14
- isMultiline: boolean;
15
- /**
16
- * Create a new line object.
17
- *
18
- * @param line - The raw content of a line.
19
- * @param isMultiline - Is the line spreading on multiple lines?
20
- */
21
- constructor(line: string, isMultiline: boolean);
22
- }
@@ -1 +0,0 @@
1
- var REGEX_LEADING_WHITESPACE=/^\s+/,REGEX_COMMENT=/^[!#]/,REGEX_TRAILING_BACKSLASHES=/(\\+)$/,PropertyLine=function(t,i){if(this.isContinuing=!1,this.isBlank=!1,this.isComment=!1,this.content=t.replace(REGEX_LEADING_WHITESPACE,""),this.isMultiline=i,0===this.content.length)this.isBlank=!0;else if(this.isMultiline||(this.isComment=REGEX_COMMENT.test(this.content)),!this.isComment){var n=this.content.match(REGEX_TRAILING_BACKSLASHES);n&&(this.isContinuing=n[1].length%2==1,this.isContinuing&&(this.content=this.content.slice(0,-1)))}};export{PropertyLine};
@@ -1,81 +0,0 @@
1
- import { PropertyLine } from './property-line.js';
2
- /**
3
- * Object representing a property (key/value).
4
- */
5
- export declare class Property {
6
- /** The content of one or multiple lines when applicable. */
7
- linesContent: string;
8
- /** The property key (unescaped). */
9
- key: string;
10
- /** The property key, including its escaped characters. */
11
- escapedKey: string;
12
- /** Is the key empty? */
13
- private hasNoKey;
14
- /** Does the key definition spread across multiple lines? */
15
- private hasMultilineKey;
16
- /** Starting line numbers of property objects with the same key. */
17
- keyCollisionLines: number[];
18
- /** Was the property's key used more than once? */
19
- hasKeyCollisions: boolean;
20
- /** The key/value pair separator */
21
- separator: string | undefined;
22
- /** The length of the key/value pair separator, including its whitespace characters. */
23
- separatorLength: number | undefined;
24
- /** The starting position of the key/value pair separator. */
25
- separatorPosition: number | undefined;
26
- /** The property value (unescaped). */
27
- value: string;
28
- /** The starting position of the value. */
29
- valuePosition: number | undefined;
30
- /** The property value, including its escaped characters. */
31
- escapedValue: string;
32
- /** Positions of the newline characters if any. */
33
- newlinePositions: number[];
34
- /** The line number at which the property starts. */
35
- readonly startingLineNumber: number;
36
- /** The line number at which the property ends. */
37
- endingLineNumber: number;
38
- /** The previous property object if it exists. */
39
- readonly previousProperty?: Property;
40
- /** The next property object if it exists. */
41
- nextProperty?: Property;
42
- /**
43
- * Create a new property object.
44
- *
45
- * @param propertyLine - A property line object.
46
- * @param startingLineNumber - The line number at which the property starts.
47
- */
48
- constructor(propertyLine: PropertyLine, startingLineNumber: number, previousProperty?: Property);
49
- /**
50
- * Set the next property object.
51
- *
52
- * @param property - The next property object
53
- */
54
- setNextProperty(property: Property): void;
55
- /**
56
- * Add the a line to a multiline property object.
57
- *
58
- * @param propertyLine - A property line object.
59
- */
60
- addLine(propertyLine: PropertyLine): void;
61
- /**
62
- * Set the property's key and value.
63
- */
64
- setKeyAndValue(): void;
65
- /**
66
- * Unescape the content from either key or value of a property.
67
- *
68
- * @param escapedContent - The content to unescape.
69
- * @param startingLineNumber - The starting line number of the content being unescaped.
70
- *
71
- * @returns The unescaped content.
72
- *
73
- * @throws {@link Error}
74
- * This exception is thrown if malformed escaped unicode characters are present.
75
- */
76
- private unescapeLine;
77
- /**
78
- * Find the character separating the key from the value.
79
- */
80
- private findSeparator;
81
- }