properties-file 3.0.0 → 3.1.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.
package/README.md CHANGED
@@ -28,7 +28,7 @@ npm install properties-file
28
28
  - A `PropertiesEditor` class enables the addition, edition, and removal of entries.
29
29
  - `escapeKey` and `escapeValue` allow the conversion of any content to a `.properties` compatible format.
30
30
  - The library also includes a Webpack loader to import `.properties` files directly into your application.
31
- - Tiny ([under 2kB compressed](https://bundlephobia.com/package/properties-file)) with 0 dependencies.
31
+ - Tiny ([under 3kB compressed](https://bundlephobia.com/package/properties-file)) with 0 dependencies.
32
32
  - 100% test coverage based on the output from a Java implementation.
33
33
  - Active maintenance (many popular `.properties` packages have been inactive for years).
34
34
 
@@ -167,14 +167,17 @@ properties.insert('newKey2', 'こんにちは', {
167
167
  escapeUnicode: true,
168
168
  })
169
169
 
170
- properties.remove('hello')
170
+ properties.delete('hello')
171
+ properties.update('world', {
172
+ newValue: 'new world',
173
+ })
171
174
  console.log(properties.format())
172
175
 
173
176
  /**
174
177
  * Outputs:
175
178
  *
176
179
  * # This is a comment
177
- * world = world
180
+ * world = new world
178
181
  * ! Below are the new keys being edited
179
182
  * newKey1 = This is my first new key
180
183
  * newKey2 = \u3053\u3093\u306b\u3061\u306f
@@ -184,6 +187,8 @@ console.log(properties.format())
184
187
  */
185
188
  ```
186
189
 
190
+ For convenience, we also added an `upsert` method that allows updating a key if it exists or adding it at the end, when it doesn't. Make sure to check in your IDE for all available methods and options in our TSDoc.
191
+
187
192
  ### Webpack File Loader
188
193
 
189
194
  If you would like to import `.properties` directly using `import`, this package comes with its own Webpack file loader located under `properties-file/webpack-loader`. Here is an example of how to configure it:
@@ -31,8 +31,8 @@ export type InsertCommentOptions = {
31
31
  /** The comment's delimiter. */
32
32
  commentDelimiter?: CommentDelimiter;
33
33
  };
34
- /** Options on the `Properties.edit` method. */
35
- export type EditOptions = {
34
+ /** Options on the `Properties.update` method. */
35
+ export type UpdateOptions = {
36
36
  /** Optionally replace the existing value with a new value. */
37
37
  newValue?: string;
38
38
  /** Optionally replace the existing key with a new key name. */
@@ -46,6 +46,17 @@ export type EditOptions = {
46
46
  /** The comment's delimiter. */
47
47
  commentDelimiter?: CommentDelimiter;
48
48
  };
49
+ /** Options on the `Properties.upsert` method. */
50
+ export type UpsertOptions = {
51
+ /** Escape unicode characters into ISO-8859-1 compatible encoding? */
52
+ escapeUnicode?: boolean;
53
+ /** The key/value separator character. */
54
+ separator?: KeyValuePairSeparator;
55
+ /** A comment to insert before. */
56
+ comment?: string;
57
+ /** The comment's delimiter. */
58
+ commentDelimiter?: CommentDelimiter;
59
+ };
49
60
  /**
50
61
  * A .properties file editor.
51
62
  */
@@ -62,22 +73,28 @@ export declare class PropertiesEditor extends Properties {
62
73
  * @param key - A property key (unescaped).
63
74
  * @param value - A property value (unescaped).
64
75
  * @param options - Additional options.
76
+ *
77
+ * @returns True if the key was inserted, otherwise false.
65
78
  */
66
- insert(key: string, value: string, options?: InsertOptions): void;
79
+ insert(key: string, value: string, options?: InsertOptions): boolean;
67
80
  /**
68
81
  * Insert a new comment in the existing object (by default it will be at the end).
69
82
  *
70
83
  * @param comment - The comment to add.
71
84
  * @param options - Additional options.
85
+ *
86
+ * @returns True if the comment was inserted, otherwise false.
72
87
  */
73
- insertComment(comment: string, options?: InsertCommentOptions): void;
88
+ insertComment(comment: string, options?: InsertCommentOptions): boolean;
74
89
  /**
75
- * Remove the last occurrence of a given key from the existing object.
90
+ * Delete the last occurrence of a given key from the existing object.
91
+ *
92
+ * @param key - The name of the key to delete.
93
+ * @param deleteCommentsAndWhiteSpace - By default, comments and white-space characters before the key will be deleted.
76
94
  *
77
- * @param key - The name of the key to remove.
78
- * @param removeCommentsAndWhiteSpace - By default, comments and white-space characters before the key will be removed.
95
+ * @returns True if the key was deleted, otherwise false.
79
96
  */
80
- remove(key: string, removeCommentsAndWhiteSpace?: boolean): void;
97
+ delete(key: string, deleteCommentsAndWhiteSpace?: boolean): boolean;
81
98
  /**
82
99
  * Restore the original newline characters of a key.
83
100
  *
@@ -95,10 +112,22 @@ export declare class PropertiesEditor extends Properties {
95
112
  */
96
113
  private getValueWithNewlines;
97
114
  /**
98
- * Edit the last occurrence of a given key from the existing object.
115
+ * Update the last occurrence of a given key from the existing object.
116
+ *
117
+ * @param key - The name of the key to update.
118
+ * @param options - Additional options.
119
+ *
120
+ * @returns True if the key was updated, otherwise false.
121
+ */
122
+ update(key: string, options?: UpdateOptions): boolean;
123
+ /**
124
+ * Update a key if it exist, otherwise add it at the end.
99
125
  *
100
- * @param key - The name of the key to edit.
126
+ * @param key - A property key (unescaped).
127
+ * @param value - A property value (unescaped).
101
128
  * @param options - Additional options.
129
+ *
130
+ * @returns True if the key was updated or inserted, otherwise false.
102
131
  */
103
- edit(key: string, options?: EditOptions): void;
132
+ upsert(key: string, value: string, options?: UpsertOptions): boolean;
104
133
  }
@@ -66,6 +66,8 @@ var PropertiesEditor = /** @class */ (function (_super) {
66
66
  * @param key - A property key (unescaped).
67
67
  * @param value - A property value (unescaped).
68
68
  * @param options - Additional options.
69
+ *
70
+ * @returns True if the key was inserted, otherwise false.
69
71
  */
70
72
  PropertiesEditor.prototype.insert = function (key, value, options) {
71
73
  var _a;
@@ -78,17 +80,17 @@ var PropertiesEditor = /** @class */ (function (_super) {
78
80
  : " ".concat(exports.DEFAULT_SEPARATOR, " ").replace(' ', ' ');
79
81
  var referenceKey = options === null || options === void 0 ? void 0 : options.referenceKey;
80
82
  var position = (options === null || options === void 0 ? void 0 : options.position) || 'after';
81
- // Allow to add multiline keys.
83
+ // Allow multiline keys.
82
84
  var multilineKey = key
83
85
  .split(/\r?\n/)
84
86
  .map(function (key) { return (0, escape_1.escapeKey)(key, escapeUnicode); })
85
87
  .join('\\\n');
86
- // Allow to add multiline values.
88
+ // Allow multiline values.
87
89
  var multilineValue = value
88
90
  .split(/\r?\n/)
89
91
  .map(function (value) { return (0, escape_1.escapeValue)(value, escapeUnicode); })
90
92
  .join('\\\n');
91
- // Allow to add multiline comments.
93
+ // Allow multiline comments.
92
94
  var commentPrefix = "".concat((options === null || options === void 0 ? void 0 : options.commentDelimiter) || exports.DEFAULT_COMMENT_DELIMITER, " ");
93
95
  var multilineComment = (options === null || options === void 0 ? void 0 : options.comment) === undefined
94
96
  ? ''
@@ -98,6 +100,7 @@ var PropertiesEditor = /** @class */ (function (_super) {
98
100
  // Insert the new property at the end if the reference key was not defined.
99
101
  (_a = this.lines).push.apply(_a, __spreadArray([], __read(newLines), false));
100
102
  this.parseLines();
103
+ return true;
101
104
  }
102
105
  else {
103
106
  // Find the last occurrence of the reference key.
@@ -110,7 +113,9 @@ var PropertiesEditor = /** @class */ (function (_super) {
110
113
  : (_c = (_b = property.previousProperty) === null || _b === void 0 ? void 0 : _b.endingLineNumber) !== null && _c !== void 0 ? _c : 0;
111
114
  this.lines = __spreadArray(__spreadArray(__spreadArray([], __read(this.lines.slice(0, insertPosition)), false), __read(newLines), false), __read(this.lines.slice(insertPosition)), false);
112
115
  this.parseLines();
116
+ return true;
113
117
  }
118
+ return false;
114
119
  }
115
120
  };
116
121
  /**
@@ -118,13 +123,15 @@ var PropertiesEditor = /** @class */ (function (_super) {
118
123
  *
119
124
  * @param comment - The comment to add.
120
125
  * @param options - Additional options.
126
+ *
127
+ * @returns True if the comment was inserted, otherwise false.
121
128
  */
122
129
  PropertiesEditor.prototype.insertComment = function (comment, options) {
123
130
  var _a;
124
131
  var _b, _c;
125
132
  var referenceKey = options === null || options === void 0 ? void 0 : options.referenceKey;
126
133
  var position = (options === null || options === void 0 ? void 0 : options.position) || 'after';
127
- // Allow to add multiline comments.
134
+ // Allow multiline comments.
128
135
  var commentPrefix = "".concat((options === null || options === void 0 ? void 0 : options.commentDelimiter) || exports.DEFAULT_COMMENT_DELIMITER, " ");
129
136
  var newLines = "".concat(commentPrefix).concat(comment)
130
137
  .replace(/\r?\n/g, "\n".concat(commentPrefix))
@@ -133,6 +140,7 @@ var PropertiesEditor = /** @class */ (function (_super) {
133
140
  // Insert the new comment at the end if the reference key was not defined.
134
141
  (_a = this.lines).push.apply(_a, __spreadArray([], __read(newLines), false));
135
142
  this.parseLines();
143
+ return true;
136
144
  }
137
145
  else {
138
146
  // Find the last occurrence of the reference key.
@@ -145,28 +153,34 @@ var PropertiesEditor = /** @class */ (function (_super) {
145
153
  : (_c = (_b = property.previousProperty) === null || _b === void 0 ? void 0 : _b.endingLineNumber) !== null && _c !== void 0 ? _c : 0;
146
154
  this.lines = __spreadArray(__spreadArray(__spreadArray([], __read(this.lines.slice(0, insertPosition)), false), __read(newLines), false), __read(this.lines.slice(insertPosition)), false);
147
155
  this.parseLines();
156
+ return true;
148
157
  }
158
+ return false;
149
159
  }
150
160
  };
151
161
  /**
152
- * Remove the last occurrence of a given key from the existing object.
162
+ * Delete the last occurrence of a given key from the existing object.
153
163
  *
154
- * @param key - The name of the key to remove.
155
- * @param removeCommentsAndWhiteSpace - By default, comments and white-space characters before the key will be removed.
164
+ * @param key - The name of the key to delete.
165
+ * @param deleteCommentsAndWhiteSpace - By default, comments and white-space characters before the key will be deleted.
166
+ *
167
+ * @returns True if the key was deleted, otherwise false.
156
168
  */
157
- PropertiesEditor.prototype.remove = function (key, removeCommentsAndWhiteSpace) {
169
+ PropertiesEditor.prototype.delete = function (key, deleteCommentsAndWhiteSpace) {
158
170
  var _a, _b;
159
- if (removeCommentsAndWhiteSpace === void 0) { removeCommentsAndWhiteSpace = true; }
171
+ if (deleteCommentsAndWhiteSpace === void 0) { deleteCommentsAndWhiteSpace = true; }
160
172
  // Find the last occurrence of the key.
161
173
  var property = __spreadArray([], __read(this.collection), false).reverse().find(function (property) { return property.key === key; });
162
174
  if (property) {
163
- var startLine = removeCommentsAndWhiteSpace
175
+ var startLine = deleteCommentsAndWhiteSpace
164
176
  ? (_b = (_a = property.previousProperty) === null || _a === void 0 ? void 0 : _a.endingLineNumber) !== null && _b !== void 0 ? _b : 0
165
177
  : property.startingLineNumber - 1;
166
178
  var endLine = property.endingLineNumber;
167
179
  this.lines = __spreadArray(__spreadArray([], __read(this.lines.slice(0, startLine)), false), __read(this.lines.slice(endLine)), false);
168
180
  this.parseLines();
181
+ return true;
169
182
  }
183
+ return false;
170
184
  };
171
185
  /**
172
186
  * Restore the original newline characters of a key.
@@ -204,45 +218,68 @@ var PropertiesEditor = /** @class */ (function (_super) {
204
218
  }, '');
205
219
  };
206
220
  /**
207
- * Edit the last occurrence of a given key from the existing object.
221
+ * Update the last occurrence of a given key from the existing object.
208
222
  *
209
- * @param key - The name of the key to edit.
223
+ * @param key - The name of the key to update.
210
224
  * @param options - Additional options.
225
+ *
226
+ * @returns True if the key was updated, otherwise false.
211
227
  */
212
- PropertiesEditor.prototype.edit = function (key, options) {
228
+ PropertiesEditor.prototype.update = function (key, options) {
213
229
  var _a, _b, _c, _d;
214
- // Find the last occurrence of the key to edit.
230
+ // Find the last occurrence of the key to update.
215
231
  var property = __spreadArray([], __read(this.collection), false).reverse().find(function (property) { return property.key === key; });
216
- if (!property) {
217
- return;
232
+ if (!property || !options) {
233
+ return false;
218
234
  }
219
- var escapeUnicode = (options === null || options === void 0 ? void 0 : options.escapeUnicode) || false;
220
- var separator = (options === null || options === void 0 ? void 0 : options.separator)
235
+ var escapeUnicode = options.escapeUnicode || false;
236
+ var separator = options.separator
221
237
  ? options.separator === ' '
222
238
  ? ' '
223
239
  : " ".concat(options.separator, " ")
224
240
  : property.separator || " ".concat(exports.DEFAULT_SEPARATOR, " ").replace(' ', ' ');
225
- // Allow to edit multiline keys.
226
- var multilineKey = ((_a = options === null || options === void 0 ? void 0 : options.newKey) !== null && _a !== void 0 ? _a : this.getKeyWithNewlines(property))
241
+ // Allow multiline keys.
242
+ var multilineKey = ((_a = options.newKey) !== null && _a !== void 0 ? _a : this.getKeyWithNewlines(property))
227
243
  .split(/\r?\n/)
228
244
  .map(function (key) { return (0, escape_1.escapeKey)(key, escapeUnicode); })
229
245
  .join('\\\n');
230
- // Allow to edit multiline values.
231
- var multilineValue = ((_b = options === null || options === void 0 ? void 0 : options.newValue) !== null && _b !== void 0 ? _b : this.getValueWithNewlines(property))
246
+ // Allow multiline values.
247
+ var multilineValue = ((_b = options.newValue) !== null && _b !== void 0 ? _b : this.getValueWithNewlines(property))
232
248
  .split(/\r?\n/)
233
249
  .map(function (value) { return (0, escape_1.escapeValue)(value, escapeUnicode); })
234
250
  .join('\\\n');
235
- // Allow to edit multiline comments.
236
- var commentPrefix = "".concat((options === null || options === void 0 ? void 0 : options.commentDelimiter) || exports.DEFAULT_COMMENT_DELIMITER, " ");
237
- var multilineComment = (options === null || options === void 0 ? void 0 : options.newComment) === undefined
251
+ // Allow multiline comments.
252
+ var commentPrefix = "".concat(options.commentDelimiter || exports.DEFAULT_COMMENT_DELIMITER, " ");
253
+ var multilineComment = options.newComment === undefined
238
254
  ? ''
239
255
  : "".concat("".concat(commentPrefix).concat(options.newComment).split(/\r?\n/).join("\n".concat(commentPrefix)), "\n");
240
256
  var newLines = "".concat(multilineComment).concat(multilineKey).concat(separator).concat(multilineValue).split(/\n/);
241
257
  // Replace the existing property with the new one.
242
- this.lines = __spreadArray(__spreadArray(__spreadArray([], __read(this.lines.slice(0, (options === null || options === void 0 ? void 0 : options.newComment) === undefined
258
+ this.lines = __spreadArray(__spreadArray(__spreadArray([], __read(this.lines.slice(0, options.newComment === undefined
243
259
  ? property.startingLineNumber - 1
244
260
  : (_d = (_c = property.previousProperty) === null || _c === void 0 ? void 0 : _c.endingLineNumber) !== null && _d !== void 0 ? _d : 0)), false), __read(newLines), false), __read(this.lines.slice(property.endingLineNumber)), false);
245
261
  this.parseLines();
262
+ return true;
263
+ };
264
+ /**
265
+ * Update a key if it exist, otherwise add it at the end.
266
+ *
267
+ * @param key - A property key (unescaped).
268
+ * @param value - A property value (unescaped).
269
+ * @param options - Additional options.
270
+ *
271
+ * @returns True if the key was updated or inserted, otherwise false.
272
+ */
273
+ PropertiesEditor.prototype.upsert = function (key, value, options) {
274
+ return this.keyLineNumbers[key]
275
+ ? this.update(key, {
276
+ newValue: value,
277
+ newComment: options === null || options === void 0 ? void 0 : options.comment,
278
+ commentDelimiter: options === null || options === void 0 ? void 0 : options.commentDelimiter,
279
+ separator: options === null || options === void 0 ? void 0 : options.separator,
280
+ escapeUnicode: options === null || options === void 0 ? void 0 : options.escapeUnicode,
281
+ })
282
+ : this.insert(key, value, options);
246
283
  };
247
284
  return PropertiesEditor;
248
285
  }(properties_1.Properties));
@@ -8,6 +8,14 @@ export declare const BOM = "\uFEFF";
8
8
  export declare const BOM_CODE_POINT: number | undefined;
9
9
  /** The default end of line character. */
10
10
  export declare const DEFAULT_END_OF_LINE_CHARACTER = "\n";
11
+ /**
12
+ * Get the first end of line (EOL) character from multiline content.
13
+ *
14
+ * @param content - The content of a `.properties` file.
15
+ *
16
+ * @returns The multiline content's first end of line (EOL) character.
17
+ */
18
+ export declare const getFirstEolCharacter: (content: string) => string | undefined;
11
19
  /**
12
20
  * A class representing the content of a .properties file.
13
21
  */
package/lib/properties.js CHANGED
@@ -27,7 +27,7 @@ var __read = (this && this.__read) || function (o, n) {
27
27
  return ar;
28
28
  };
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.KeyCollisions = exports.Properties = exports.DEFAULT_END_OF_LINE_CHARACTER = exports.BOM_CODE_POINT = exports.BOM = void 0;
30
+ exports.KeyCollisions = exports.Properties = exports.getFirstEolCharacter = exports.DEFAULT_END_OF_LINE_CHARACTER = exports.BOM_CODE_POINT = exports.BOM = void 0;
31
31
  var property_1 = require("./property");
32
32
  var property_line_1 = require("./property-line");
33
33
  /**
@@ -48,6 +48,7 @@ var getFirstEolCharacter = function (content) {
48
48
  var newlineIndex = content.indexOf('\n');
49
49
  return newlineIndex < 0 ? undefined : "".concat(content[newlineIndex - 1] === '\r' ? '\r' : '', "\n");
50
50
  };
51
+ exports.getFirstEolCharacter = getFirstEolCharacter;
51
52
  /**
52
53
  * A class representing the content of a .properties file.
53
54
  */
@@ -63,9 +64,9 @@ var Properties = /** @class */ (function () {
63
64
  this.collection = [];
64
65
  /** Object associating keys with their starting line numbers. */
65
66
  this.keyLineNumbers = {};
66
- var stringContent = Buffer.isBuffer(content) ? content.toString() : content;
67
+ var stringContent = typeof content === 'string' ? content : content.toString();
67
68
  this.hasBom = stringContent.codePointAt(0) === exports.BOM_CODE_POINT;
68
- this.eolCharacter = (_a = getFirstEolCharacter(stringContent)) !== null && _a !== void 0 ? _a : exports.DEFAULT_END_OF_LINE_CHARACTER;
69
+ this.eolCharacter = (_a = (0, exports.getFirstEolCharacter)(stringContent)) !== null && _a !== void 0 ? _a : exports.DEFAULT_END_OF_LINE_CHARACTER;
69
70
  this.lines = (this.hasBom ? stringContent.slice(1) : stringContent).split(/\r?\n/);
70
71
  this.parseLines();
71
72
  }
@@ -134,7 +135,7 @@ var Properties = /** @class */ (function () {
134
135
  this.keyLineNumbers[property.key].push(property.startingLineNumber);
135
136
  property.hasKeyCollisions = true;
136
137
  property.keyCollisionLines = this.keyLineNumbers[property.key];
137
- // Remove collision so that we can overwrite it with the latest object.
138
+ // Remove the collision from the collection (we only keep latest value).
138
139
  this.collection = this.collection.filter(function (existingPropertyObject) { return existingPropertyObject.key !== property.key; });
139
140
  }
140
141
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "properties-file",
3
- "version": "3.0.0",
3
+ "version": "3.1.1",
4
4
  "description": ".properties file parser, editor, formatter and Webpack loader.",
5
5
  "keywords": [
6
6
  ".properties",
@@ -54,7 +54,7 @@
54
54
  "scripts": {
55
55
  "add-import-type": "ts-node ./src/add-import-type.ts && rm -f ./lib/add-import-type.*",
56
56
  "build": "npm run prettier && npm run lint-fix && rm -Rf ./lib && tsc && npm run add-import-type && npm run test",
57
- "ci": "npm run lint-check && rm -Rf ./lib && tsc && npm run add-import-type && npm run test",
57
+ "ci": "npm run build",
58
58
  "lint-check": "eslint --ext .js --ext .jsx --ext .ts --ext .tsx --ext .json .",
59
59
  "lint-fix": "eslint --ext .js --ext .jsx --ext .ts --ext .tsx --ext .json --fix .",
60
60
  "lint-print-config": "eslint --print-config ./eslintrc.yaml",
@@ -65,8 +65,8 @@
65
65
  "devDependencies": {
66
66
  "@release-it/conventional-changelog": "5.1.1",
67
67
  "@types/jest": "29.5.1",
68
- "@typescript-eslint/eslint-plugin": "5.59.0",
69
- "@typescript-eslint/parser": "5.59.0",
68
+ "@typescript-eslint/eslint-plugin": "5.59.1",
69
+ "@typescript-eslint/parser": "5.59.1",
70
70
  "dotenv-cli": "7.2.1",
71
71
  "eslint": "8.39.0",
72
72
  "eslint-config-prettier": "8.8.0",
@@ -83,7 +83,7 @@
83
83
  "prettier": "2.8.8",
84
84
  "prettier-plugin-organize-imports": "3.2.2",
85
85
  "prettier-plugin-sh": "0.12.8",
86
- "release-it": "15.10.1",
86
+ "release-it": "15.10.2",
87
87
  "ts-jest": "29.1.0",
88
88
  "ts-node": "10.9.1",
89
89
  "typescript": "5.0.4"