complete-common 2.7.0 → 2.8.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.
@@ -28,6 +28,8 @@ export declare function hasDiacritic(string: string): boolean;
28
28
  export declare function hasEmoji(string: string): boolean;
29
29
  /** From: https://stackoverflow.com/questions/1731190/check-if-a-string-has-white-space */
30
30
  export declare function hasWhitespace(string: string): boolean;
31
+ /** Helper function to determine if a string only contains ASCII characters. */
32
+ export declare function isASCII(str: string): boolean;
31
33
  /**
32
34
  * From:
33
35
  * https://stackoverflow.com/questions/8334606/check-if-first-letter-of-word-is-a-capital-letter
@@ -28,6 +28,8 @@ export declare function hasDiacritic(string: string): boolean;
28
28
  export declare function hasEmoji(string: string): boolean;
29
29
  /** From: https://stackoverflow.com/questions/1731190/check-if-a-string-has-white-space */
30
30
  export declare function hasWhitespace(string: string): boolean;
31
+ /** Helper function to determine if a string only contains ASCII characters. */
32
+ export declare function isASCII(str: string): boolean;
31
33
  /**
32
34
  * From:
33
35
  * https://stackoverflow.com/questions/8334606/check-if-first-letter-of-word-is-a-capital-letter
@@ -28,6 +28,8 @@ export declare function hasDiacritic(string: string): boolean;
28
28
  export declare function hasEmoji(string: string): boolean;
29
29
  /** From: https://stackoverflow.com/questions/1731190/check-if-a-string-has-white-space */
30
30
  export declare function hasWhitespace(string: string): boolean;
31
+ /** Helper function to determine if a string only contains ASCII characters. */
32
+ export declare function isASCII(str: string): boolean;
31
33
  /**
32
34
  * From:
33
35
  * https://stackoverflow.com/questions/8334606/check-if-first-letter-of-word-is-a-capital-letter
@@ -1 +1 @@
1
- {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/functions/string.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAU5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqBlE;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiBtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GACtD;IACE,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IAErB,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IAErB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;CACtB,GACD,SAAS,CAwBZ;AAGD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,MAAM,CAuBR;AAED,gGAAgG;AAChG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzE;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,UAAQ,GACd,MAAM,CAWR;AAED,gGAAgG;AAChG,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAMxE"}
1
+ {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/functions/string.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAU5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqBlE;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE5C;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiBtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GACtD;IACE,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IAErB,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IAErB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;CACtB,GACD,SAAS,CAwBZ;AAGD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,MAAM,CAuBR;AAED,gGAAgG;AAChG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzE;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,UAAQ,GACd,MAAM,CAWR;AAED,gGAAgG;AAChG,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAMxE"}
package/dist/index.cjs CHANGED
@@ -399,8 +399,9 @@ function repeat(num, func) {
399
399
  function todo(...args) {
400
400
  }
401
401
 
402
+ const ASCII_REGEX = /^[\u0000-\u007F]*$/;
402
403
  const DIACRITIC_REGEX = /\p{Diacritic}/u;
403
- const EMOJI_REGEX = /(\p{Extended_Pictographic}|\p{Emoji_Component})/u;
404
+ const EMOJI_REGEX = /(\p{Extended_Pictographic}|[#*0-9]\uFE0F?\u20E3)/u;
404
405
  const FIRST_LETTER_CAPITALIZED_REGEX = /^\p{Lu}/u;
405
406
  const KEBAB_CASE_REGEX = /^[\da-z]+(?:-[\da-z]+)*$/;
406
407
  const SEMANTIC_VERSION_REGEX = /^v*(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/;
@@ -445,6 +446,9 @@ function hasEmoji(string) {
445
446
  function hasWhitespace(string) {
446
447
  return WHITESPACE_REGEX.test(string);
447
448
  }
449
+ function isASCII(str) {
450
+ return ASCII_REGEX.test(str);
451
+ }
448
452
  function isFirstLetterCapitalized(string) {
449
453
  return FIRST_LETTER_CAPITALIZED_REGEX.test(string);
450
454
  }
@@ -614,6 +618,7 @@ exports.iRange = iRange;
614
618
  exports.includes = includes;
615
619
  exports.includesAny = includesAny;
616
620
  exports.interfaceSatisfiesEnum = interfaceSatisfiesEnum;
621
+ exports.isASCII = isASCII;
617
622
  exports.isArray = isArray;
618
623
  exports.isArrayBoolean = isArrayBoolean;
619
624
  exports.isArrayNumber = isArrayNumber;
package/dist/index.mjs CHANGED
@@ -397,8 +397,9 @@ function repeat(num, func) {
397
397
  function todo(...args) {
398
398
  }
399
399
 
400
+ const ASCII_REGEX = /^[\u0000-\u007F]*$/;
400
401
  const DIACRITIC_REGEX = /\p{Diacritic}/u;
401
- const EMOJI_REGEX = /(\p{Extended_Pictographic}|\p{Emoji_Component})/u;
402
+ const EMOJI_REGEX = /(\p{Extended_Pictographic}|[#*0-9]\uFE0F?\u20E3)/u;
402
403
  const FIRST_LETTER_CAPITALIZED_REGEX = /^\p{Lu}/u;
403
404
  const KEBAB_CASE_REGEX = /^[\da-z]+(?:-[\da-z]+)*$/;
404
405
  const SEMANTIC_VERSION_REGEX = /^v*(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/;
@@ -443,6 +444,9 @@ function hasEmoji(string) {
443
444
  function hasWhitespace(string) {
444
445
  return WHITESPACE_REGEX.test(string);
445
446
  }
447
+ function isASCII(str) {
448
+ return ASCII_REGEX.test(str);
449
+ }
446
450
  function isFirstLetterCapitalized(string) {
447
451
  return FIRST_LETTER_CAPITALIZED_REGEX.test(string);
448
452
  }
@@ -566,4 +570,4 @@ function* tupleKeys(tuple) {
566
570
 
567
571
  const ReadonlyMap = Map;
568
572
 
569
- export { HOUR_IN_MILLISECONDS, MINUTE_IN_MILLISECONDS, ReadonlyMap, ReadonlySet, SECOND_IN_MILLISECONDS, addSetsToSet, arrayCopyTwoDimensional, arrayEquals, arrayRemove, arrayRemoveAllInPlace, arrayRemoveInPlace, assertArray, assertArrayBoolean, assertArrayNumber, assertArrayString, assertBoolean, assertDefined, assertEnumValue, assertIs, assertNotNull, assertNumber, assertObject, assertString, capitalizeFirstLetter, clamp, combineSets, copySet, eRange, emptyArray, escapeHTMLCharacters, filterMap, getElapsedSeconds, getEnumEntries, getEnumKeys, getEnumValues, getNumConsecutiveDiacritics, getRandomArrayElement, getRandomArrayIndex, getRandomInt, hasDiacritic, hasEmoji, hasWhitespace, iRange, includes, includesAny, interfaceSatisfiesEnum, isArray, isArrayBoolean, isArrayNumber, isArrayString, isEnumValue, isFirstLetterCapitalized, isKebabCase, isKeyOf, isLowerCase, isObject, isSemanticVersion, isUpperCase, kebabCaseToCamelCase, kebabCaseToPascalCase, mapFilter, mapFind, newArray, noop, normalizeString, objectFilter, objectKeysToSet, objectToMap, objectToReverseMap, objectValuesToSet, parseFloatSafe, parseIntSafe, parseSemanticVersion, removeLinesBetweenMarkers, removeLinesMatching, removeNonPrintableCharacters, removeWhitespace, repeat, setAdd, setHas, sortCaseInsensitive, sumArray, todo, trimPrefix, trimSuffix, truncateString, tupleEntries, tupleKeys };
573
+ export { HOUR_IN_MILLISECONDS, MINUTE_IN_MILLISECONDS, ReadonlyMap, ReadonlySet, SECOND_IN_MILLISECONDS, addSetsToSet, arrayCopyTwoDimensional, arrayEquals, arrayRemove, arrayRemoveAllInPlace, arrayRemoveInPlace, assertArray, assertArrayBoolean, assertArrayNumber, assertArrayString, assertBoolean, assertDefined, assertEnumValue, assertIs, assertNotNull, assertNumber, assertObject, assertString, capitalizeFirstLetter, clamp, combineSets, copySet, eRange, emptyArray, escapeHTMLCharacters, filterMap, getElapsedSeconds, getEnumEntries, getEnumKeys, getEnumValues, getNumConsecutiveDiacritics, getRandomArrayElement, getRandomArrayIndex, getRandomInt, hasDiacritic, hasEmoji, hasWhitespace, iRange, includes, includesAny, interfaceSatisfiesEnum, isASCII, isArray, isArrayBoolean, isArrayNumber, isArrayString, isEnumValue, isFirstLetterCapitalized, isKebabCase, isKeyOf, isLowerCase, isObject, isSemanticVersion, isUpperCase, kebabCaseToCamelCase, kebabCaseToPascalCase, mapFilter, mapFind, newArray, noop, normalizeString, objectFilter, objectKeysToSet, objectToMap, objectToReverseMap, objectValuesToSet, parseFloatSafe, parseIntSafe, parseSemanticVersion, removeLinesBetweenMarkers, removeLinesMatching, removeNonPrintableCharacters, removeWhitespace, repeat, setAdd, setHas, sortCaseInsensitive, sumArray, todo, trimPrefix, trimSuffix, truncateString, tupleEntries, tupleKeys };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "complete-common",
3
- "version": "2.7.0",
3
+ "version": "2.8.0",
4
4
  "description": "Helper functions for TypeScript projects.",
5
5
  "homepage": "https://complete-ts.github.io/",
6
6
  "bugs": {
@@ -31,8 +31,8 @@
31
31
  "test": "tsx --test"
32
32
  },
33
33
  "devDependencies": {
34
- "@types/node": "24.7.1",
35
- "complete-node": "12.2.0",
34
+ "@types/node": "24.7.2",
35
+ "complete-node": "12.2.1",
36
36
  "eslint-plugin-sort-exports": "0.9.1",
37
37
  "typescript": "5.9.3",
38
38
  "typescript-eslint": "8.46.0",
@@ -9,14 +9,27 @@ import {
9
9
  } from "./string.js";
10
10
 
11
11
  describe("hasEmoji", () => {
12
- test("should return true for string with emoji", () => {
12
+ test("should return true for string with normal emoji", () => {
13
13
  equal(hasEmoji("Hello 😃 World"), true);
14
- equal(hasEmoji("This is a 🌟 test"), true);
14
+ });
15
+
16
+ test("should return true for string with keycap emoji", () => {
17
+ equal(hasEmoji("This is a keycap emoji: #️⃣"), true);
15
18
  });
16
19
 
17
20
  test("should return false for string without emoji", () => {
18
21
  equal(hasEmoji("Hello World"), false);
19
- equal(hasEmoji("No emoji here!"), false);
22
+ equal(
23
+ hasEmoji(`
24
+ # Some Markdown Title
25
+
26
+ This page is for people who like [cake](https://en.wikipedia.org/wiki/Cake).
27
+
28
+ - Run \`npm run cake\` to get cake.
29
+ - Run \`npm run pie\` to get pie.
30
+ `),
31
+ false,
32
+ );
20
33
  });
21
34
 
22
35
  test("should handle empty string", () => {
@@ -123,9 +136,11 @@ describe("trimPrefix", () => {
123
136
  });
124
137
 
125
138
  describe("trimSuffix", () => {
126
- equal(trimSuffix("foo", ""), "foo");
127
- equal(trimSuffix("foo", "o"), "fo");
128
- equal(trimSuffix("foo", "oo"), "f");
129
- equal(trimSuffix("foo", "foo"), "");
130
- equal(trimSuffix("foo", "1foo"), "foo");
139
+ test(() => {
140
+ equal(trimSuffix("foo", ""), "foo");
141
+ equal(trimSuffix("foo", "o"), "fo");
142
+ equal(trimSuffix("foo", "oo"), "f");
143
+ equal(trimSuffix("foo", "foo"), "");
144
+ equal(trimSuffix("foo", "1foo"), "foo");
145
+ });
131
146
  });
@@ -9,10 +9,16 @@ import { parseIntSafe } from "./utils.js";
9
9
  // When regular expressions are located at the root instead of inside the function, the functions
10
10
  // are tested to perform 11% faster.
11
11
 
12
+ // eslint-disable-next-line no-control-regex
13
+ const ASCII_REGEX = /^[\u0000-\u007F]*$/;
14
+
12
15
  const DIACRITIC_REGEX = /\p{Diacritic}/u;
13
16
 
14
- /** This is what the Zod validator library uses. */
15
- const EMOJI_REGEX = /(\p{Extended_Pictographic}|\p{Emoji_Component})/u;
17
+ /**
18
+ * - We can't use `/\p{Emoji}/u` because it has a false positive on "#" characters.
19
+ * - We can't use `/\p{Extended_Pictographic}/u` because it has a false negative on keycap emojis.
20
+ */
21
+ const EMOJI_REGEX = /(\p{Extended_Pictographic}|[#*0-9]\uFE0F?\u20E3)/u;
16
22
 
17
23
  const FIRST_LETTER_CAPITALIZED_REGEX = /^\p{Lu}/u;
18
24
  const KEBAB_CASE_REGEX = /^[\da-z]+(?:-[\da-z]+)*$/;
@@ -101,6 +107,11 @@ export function hasWhitespace(string: string): boolean {
101
107
  return WHITESPACE_REGEX.test(string);
102
108
  }
103
109
 
110
+ /** Helper function to determine if a string only contains ASCII characters. */
111
+ export function isASCII(str: string): boolean {
112
+ return ASCII_REGEX.test(str);
113
+ }
114
+
104
115
  /**
105
116
  * From:
106
117
  * https://stackoverflow.com/questions/8334606/check-if-first-letter-of-word-is-a-capital-letter