trousse 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![npm version](https://img.shields.io/npm/v/trousse.svg)](https://www.npmjs.com/package/trousse)
5
5
  [![license](https://img.shields.io/npm/l/trousse.svg)](https://github.com/macieklamberski/trousse/blob/main/LICENSE)
6
6
 
7
- Personal toolbox of shared TypeScript utilities used across my projects: type guards, coercions, matching and array helpers.
7
+ Personal toolbox of shared TypeScript utilities used across my projects: type guards, coercions, matching, array and locale interpolation helpers.
8
8
 
9
9
  ## Installation
10
10
 
package/dist/index.d.ts CHANGED
@@ -3,7 +3,8 @@ import { MaybePromise, Nullish, Pattern } from "./types.js";
3
3
  import { coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString } from "./coercions.js";
4
4
  import { isBoolean, isFunction, isNonEmptyString, isNullish, isNumber, isObject, isPlainObject, isPresent, isString, isValidDate } from "./is.js";
5
5
  import { isJsonLike, isParseableJson } from "./json.js";
6
+ import { escapeHtml, t, tx } from "./locales.js";
6
7
  import { anyWordMatchesAnyOf, endsWithAnyOf, includesAnyOf, isAnyOf, startsWithAnyOf } from "./matching.js";
7
8
  import { sleep } from "./timers.js";
8
9
  import { getPathSegments, isHostOf, isSubdomainOf, parseUrl } from "./urls.js";
9
- export { type MaybePromise, type Nullish, type Pattern, anyWordMatchesAnyOf, coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString, endsWithAnyOf, getPathSegments, includesAnyOf, isAnyOf, isBoolean, isFunction, isHostOf, isJsonLike, isNonEmptyString, isNullish, isNumber, isObject, isParseableJson, isPlainObject, isPresent, isString, isSubdomainOf, isValidDate, omitEmpty, parseUrl, sleep, startsWithAnyOf };
10
+ export { type MaybePromise, type Nullish, type Pattern, anyWordMatchesAnyOf, coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString, endsWithAnyOf, escapeHtml, getPathSegments, includesAnyOf, isAnyOf, isBoolean, isFunction, isHostOf, isJsonLike, isNonEmptyString, isNullish, isNumber, isObject, isParseableJson, isPlainObject, isPresent, isString, isSubdomainOf, isValidDate, omitEmpty, parseUrl, sleep, startsWithAnyOf, t, tx };
package/dist/index.js CHANGED
@@ -2,7 +2,8 @@ import { isBoolean, isFunction, isNonEmptyString, isNullish, isNumber, isObject,
2
2
  import { omitEmpty } from "./arrays.js";
3
3
  import { coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString } from "./coercions.js";
4
4
  import { isJsonLike, isParseableJson } from "./json.js";
5
+ import { escapeHtml, t, tx } from "./locales.js";
5
6
  import { anyWordMatchesAnyOf, endsWithAnyOf, includesAnyOf, isAnyOf, startsWithAnyOf } from "./matching.js";
6
7
  import { sleep } from "./timers.js";
7
8
  import { getPathSegments, isHostOf, isSubdomainOf, parseUrl } from "./urls.js";
8
- export { anyWordMatchesAnyOf, coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString, endsWithAnyOf, getPathSegments, includesAnyOf, isAnyOf, isBoolean, isFunction, isHostOf, isJsonLike, isNonEmptyString, isNullish, isNumber, isObject, isParseableJson, isPlainObject, isPresent, isString, isSubdomainOf, isValidDate, omitEmpty, parseUrl, sleep, startsWithAnyOf };
9
+ export { anyWordMatchesAnyOf, coerceArray, coerceBoolean, coerceDate, coerceNumber, coerceSingular, coerceString, endsWithAnyOf, escapeHtml, getPathSegments, includesAnyOf, isAnyOf, isBoolean, isFunction, isHostOf, isJsonLike, isNonEmptyString, isNullish, isNumber, isObject, isParseableJson, isPlainObject, isPresent, isString, isSubdomainOf, isValidDate, omitEmpty, parseUrl, sleep, startsWithAnyOf, t, tx };
package/dist/is.js CHANGED
@@ -25,7 +25,10 @@ const isPlainObject = (value) => {
25
25
  };
26
26
  const whitespaceOnlyRegex = /^\p{White_Space}*$/u;
27
27
  const isNonEmptyString = (value) => {
28
- return isString(value) && value !== "" && !whitespaceOnlyRegex.test(value);
28
+ if (!isString(value) || value === "") return false;
29
+ const code = value.charCodeAt(0);
30
+ if (code > 32 && code < 127) return true;
31
+ return !whitespaceOnlyRegex.test(value);
29
32
  };
30
33
  const isValidDate = (value) => {
31
34
  return value instanceof Date && !Number.isNaN(value.getTime());
package/dist/json.js CHANGED
@@ -1,11 +1,16 @@
1
1
  //#region src/json.ts
2
- const jsonObjectStartRegex = /^\s*\{/;
3
- const jsonObjectEndRegex = /\}\s*$/;
4
- const jsonArrayStartRegex = /^\s*\[/;
5
- const jsonArrayEndRegex = /\]\s*$/;
2
+ const isWhitespaceCode = (code) => {
3
+ return code >= 9 && code <= 13 || code === 32 || code === 160 || code === 5760 || code >= 8192 && code <= 8202 || code === 8232 || code === 8233 || code === 8239 || code === 8287 || code === 12288 || code === 65279;
4
+ };
6
5
  const isJsonLike = (value) => {
7
6
  if (value.length < 2) return false;
8
- return jsonObjectStartRegex.test(value) && jsonObjectEndRegex.test(value) || jsonArrayStartRegex.test(value) && jsonArrayEndRegex.test(value);
7
+ let start = 0;
8
+ let end = value.length - 1;
9
+ while (start < end && isWhitespaceCode(value.charCodeAt(start))) start++;
10
+ while (end > start && isWhitespaceCode(value.charCodeAt(end))) end--;
11
+ const first = value.charCodeAt(start);
12
+ const last = value.charCodeAt(end);
13
+ return first === 123 && last === 125 || first === 91 && last === 93;
9
14
  };
10
15
  const isParseableJson = (value) => {
11
16
  try {
@@ -0,0 +1,6 @@
1
+ //#region src/locales.d.ts
2
+ declare const escapeHtml: (value: string) => string;
3
+ declare const t: (template: string, params: Record<string, string | number>) => string;
4
+ declare const tx: (template: string, params: Record<string, string | number>) => string;
5
+ //#endregion
6
+ export { escapeHtml, t, tx };
@@ -0,0 +1,22 @@
1
+ //#region src/locales.ts
2
+ const placeholderRegex = /\{\{(\w+)\}\}/g;
3
+ const escapableRegex = /[&<>"']/g;
4
+ const escapeHtml = (value) => {
5
+ return value.replace(escapableRegex, (char) => {
6
+ switch (char) {
7
+ case "&": return "&amp;";
8
+ case "<": return "&lt;";
9
+ case ">": return "&gt;";
10
+ case "\"": return "&quot;";
11
+ default: return "&#39;";
12
+ }
13
+ });
14
+ };
15
+ const t = (template, params) => {
16
+ return template.replace(placeholderRegex, (_, key) => String(params[key]));
17
+ };
18
+ const tx = (template, params) => {
19
+ return template.replace(placeholderRegex, (_, key) => escapeHtml(String(params[key])));
20
+ };
21
+ //#endregion
22
+ export { escapeHtml, t, tx };
package/dist/matching.js CHANGED
@@ -29,7 +29,16 @@ const endsWithAnyOf = (value, patterns) => {
29
29
  });
30
30
  };
31
31
  const anyWordMatchesAnyOf = (value, patterns) => {
32
- return value.toLowerCase().split(whitespaceRegex).some((word) => isAnyOf(word, patterns));
32
+ const stringPatterns = [];
33
+ const regexPatterns = [];
34
+ for (const pattern of patterns) if (pattern instanceof RegExp) regexPatterns.push(pattern);
35
+ else stringPatterns.push(pattern.toLowerCase().trim());
36
+ const words = value.toLowerCase().split(whitespaceRegex);
37
+ for (const word of words) {
38
+ for (const stringPattern of stringPatterns) if (word === stringPattern) return true;
39
+ for (const regexPattern of regexPatterns) if (regexPattern.test(word)) return true;
40
+ }
41
+ return false;
33
42
  };
34
43
  //#endregion
35
44
  export { anyWordMatchesAnyOf, endsWithAnyOf, includesAnyOf, isAnyOf, startsWithAnyOf };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trousse",
3
- "description": "Personal toolbox of shared TypeScript utilities: type guards, coercions, matching and array helpers.",
3
+ "description": "Personal toolbox of shared TypeScript utilities: type guards, coercions, matching, array and locale interpolation helpers.",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/macieklamberski/trousse.git"
@@ -40,5 +40,5 @@
40
40
  "kvalita": "^1.15.0",
41
41
  "tsdown": "^0.22.2"
42
42
  },
43
- "version": "1.0.0"
43
+ "version": "1.1.0"
44
44
  }