stringzy 3.0.0 → 4.0.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.
Files changed (111) hide show
  1. package/.prettierignore +4 -0
  2. package/.prettierrc +7 -0
  3. package/CONTRIBUTING.md +41 -29
  4. package/README.md +397 -160
  5. package/dist/analyzing/characterCount.d.ts +19 -0
  6. package/dist/analyzing/characterCount.js +21 -2
  7. package/dist/analyzing/characterFrequency.d.ts +19 -0
  8. package/dist/analyzing/characterFrequency.js +22 -3
  9. package/dist/analyzing/complexity.d.ts +33 -0
  10. package/dist/analyzing/complexity.js +35 -2
  11. package/dist/analyzing/index.d.ts +18 -12
  12. package/dist/analyzing/index.js +10 -2
  13. package/dist/analyzing/patternCount.d.ts +10 -0
  14. package/dist/analyzing/patternCount.js +52 -0
  15. package/dist/analyzing/stringSimilarity.js +1 -1
  16. package/dist/analyzing/vowelConsonantCount.d.ts +22 -0
  17. package/dist/analyzing/vowelConsonantCount.js +38 -0
  18. package/dist/analyzing/wordCount.d.ts +22 -0
  19. package/dist/analyzing/wordCount.js +24 -2
  20. package/dist/formatting/capitalize.d.ts +21 -0
  21. package/dist/formatting/capitalize.js +22 -1
  22. package/dist/formatting/index.d.ts +6 -6
  23. package/dist/formatting/number.d.ts +23 -0
  24. package/dist/formatting/number.js +24 -1
  25. package/dist/formatting/phone.d.ts +23 -0
  26. package/dist/formatting/phone.js +23 -0
  27. package/dist/index.d.ts +9 -4
  28. package/dist/tests/analyzing/patternCount.test.d.ts +1 -0
  29. package/dist/tests/analyzing/patternCount.test.js +34 -0
  30. package/dist/tests/analyzing/readingDuration.test.js +12 -12
  31. package/dist/tests/analyzing/vowelConsonantCount.test.d.ts +1 -0
  32. package/dist/tests/analyzing/vowelConsonantCount.test.js +25 -0
  33. package/dist/tests/transformations/numberToText.test.d.ts +1 -0
  34. package/dist/tests/transformations/numberToText.test.js +60 -0
  35. package/dist/tests/transformations/splitChunks.test.d.ts +1 -0
  36. package/dist/tests/transformations/splitChunks.test.js +31 -0
  37. package/dist/tests/validations/isCoordinates.test.d.ts +1 -0
  38. package/dist/tests/validations/isCoordinates.test.js +18 -0
  39. package/dist/tests/validations/isEmail.smtpUTF8.test.d.ts +1 -0
  40. package/dist/tests/validations/isEmail.smtpUTF8.test.js +16 -0
  41. package/dist/tests/validations/isEmail.test.js +56 -6
  42. package/dist/tests/validations/isHexColor.test.js +21 -21
  43. package/dist/tests/validations/isPalindrome.test.d.ts +1 -0
  44. package/dist/tests/validations/isPalindrome.test.js +39 -0
  45. package/dist/tests/validations/isTypeOf.test.d.ts +1 -0
  46. package/dist/tests/validations/isTypeOf.test.js +28 -0
  47. package/dist/transformations/camelCase.d.ts +24 -0
  48. package/dist/transformations/camelCase.js +24 -0
  49. package/dist/transformations/capitalizeWords.d.ts +21 -0
  50. package/dist/transformations/capitalizeWords.js +23 -2
  51. package/dist/transformations/constantCase.d.ts +26 -0
  52. package/dist/transformations/constantCase.js +26 -0
  53. package/dist/transformations/escapeHTML.d.ts +23 -0
  54. package/dist/transformations/escapeHTML.js +24 -2
  55. package/dist/transformations/index.d.ts +3 -0
  56. package/dist/transformations/index.js +6 -2
  57. package/dist/transformations/initials.d.ts +27 -0
  58. package/dist/transformations/initials.js +38 -8
  59. package/dist/transformations/kebabCase.d.ts +26 -0
  60. package/dist/transformations/kebabCase.js +26 -0
  61. package/dist/transformations/maskSegment.js +4 -6
  62. package/dist/transformations/numberToText/helpers.d.ts +10 -0
  63. package/dist/transformations/numberToText/helpers.js +31 -0
  64. package/dist/transformations/numberToText/implementation_EN.d.ts +10 -0
  65. package/dist/transformations/numberToText/implementation_EN.js +45 -0
  66. package/dist/transformations/numberToText/implementation_PL.d.ts +10 -0
  67. package/dist/transformations/numberToText/implementation_PL.js +79 -0
  68. package/dist/transformations/numberToText/main.d.ts +19 -0
  69. package/dist/transformations/numberToText/main.js +67 -0
  70. package/dist/transformations/numberToText/types.d.ts +3 -0
  71. package/dist/transformations/numberToText/types.js +82 -0
  72. package/dist/transformations/pascalCase.d.ts +25 -0
  73. package/dist/transformations/pascalCase.js +25 -0
  74. package/dist/transformations/removeDuplicates.d.ts +21 -0
  75. package/dist/transformations/removeDuplicates.js +25 -4
  76. package/dist/transformations/removeSpecialChars.d.ts +22 -0
  77. package/dist/transformations/removeSpecialChars.js +26 -4
  78. package/dist/transformations/removeWords.d.ts +27 -0
  79. package/dist/transformations/removeWords.js +31 -4
  80. package/dist/transformations/snakeCase.d.ts +26 -0
  81. package/dist/transformations/snakeCase.js +26 -0
  82. package/dist/transformations/splitChunks.d.ts +8 -0
  83. package/dist/transformations/splitChunks.js +24 -0
  84. package/dist/transformations/titleCase.d.ts +25 -0
  85. package/dist/transformations/titleCase.js +25 -0
  86. package/dist/transformations/toSlug.d.ts +24 -0
  87. package/dist/transformations/toSlug.js +28 -4
  88. package/dist/transformations/truncateText.d.ts +25 -0
  89. package/dist/transformations/truncateText.js +28 -3
  90. package/dist/validations/index.d.ts +6 -0
  91. package/dist/validations/index.js +10 -2
  92. package/dist/validations/isCoordinates.d.ts +8 -0
  93. package/dist/validations/isCoordinates.js +19 -0
  94. package/dist/validations/isDate.d.ts +1 -1
  95. package/dist/validations/isDate.js +6 -8
  96. package/dist/validations/isEmail.d.ts +13 -1
  97. package/dist/validations/isEmail.js +176 -3
  98. package/dist/validations/isEmpty.d.ts +9 -0
  99. package/dist/validations/isEmpty.js +9 -0
  100. package/dist/validations/isHexColor.js +1 -1
  101. package/dist/validations/isIPv4.d.ts +21 -0
  102. package/dist/validations/isIPv4.js +22 -2
  103. package/dist/validations/isPalindrome.d.ts +10 -0
  104. package/dist/validations/isPalindrome.js +21 -0
  105. package/dist/validations/isSlug.d.ts +27 -0
  106. package/dist/validations/isSlug.js +27 -0
  107. package/dist/validations/isTypeOf.d.ts +9 -0
  108. package/dist/validations/isTypeOf.js +30 -0
  109. package/dist/validations/isURL.d.ts +21 -0
  110. package/dist/validations/isURL.js +21 -0
  111. package/package.json +5 -3
@@ -1,3 +1,4 @@
1
+ export { isCoordinates } from './isCoordinates';
1
2
  export { isDate } from './isDate';
2
3
  export { isEmail } from './isEmail';
3
4
  export { isEmpty } from './isEmpty';
@@ -5,6 +6,8 @@ export { isSlug } from './isSlug';
5
6
  export { isURL } from './isURL';
6
7
  export { isIPv4 } from './isIPv4';
7
8
  export { isHexColor } from './isHexColor';
9
+ export { isPalindrome } from './isPalindrome';
10
+ import { isCoordinates } from './isCoordinates';
8
11
  import { isDate } from './isDate';
9
12
  import { isEmail } from './isEmail';
10
13
  import { isEmpty } from './isEmpty';
@@ -12,7 +15,9 @@ import { isSlug } from './isSlug';
12
15
  import { isURL } from './isURL';
13
16
  import { isIPv4 } from './isIPv4';
14
17
  import { isHexColor } from './isHexColor';
18
+ import { isPalindrome } from './isPalindrome';
15
19
  export declare const validations: {
20
+ isCoordinates: typeof isCoordinates;
16
21
  isDate: typeof isDate;
17
22
  isEmail: typeof isEmail;
18
23
  isEmpty: typeof isEmpty;
@@ -20,4 +25,5 @@ export declare const validations: {
20
25
  isURL: typeof isURL;
21
26
  isIPv4: typeof isIPv4;
22
27
  isHexColor: typeof isHexColor;
28
+ isPalindrome: typeof isPalindrome;
23
29
  };
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validations = exports.isHexColor = exports.isIPv4 = exports.isURL = exports.isSlug = exports.isEmpty = exports.isEmail = exports.isDate = void 0;
3
+ exports.validations = exports.isPalindrome = exports.isHexColor = exports.isIPv4 = exports.isURL = exports.isSlug = exports.isEmpty = exports.isEmail = exports.isDate = exports.isCoordinates = void 0;
4
+ var isCoordinates_1 = require("./isCoordinates");
5
+ Object.defineProperty(exports, "isCoordinates", { enumerable: true, get: function () { return isCoordinates_1.isCoordinates; } });
4
6
  var isDate_1 = require("./isDate");
5
7
  Object.defineProperty(exports, "isDate", { enumerable: true, get: function () { return isDate_1.isDate; } });
6
8
  var isEmail_1 = require("./isEmail");
@@ -15,6 +17,9 @@ var isIPv4_1 = require("./isIPv4");
15
17
  Object.defineProperty(exports, "isIPv4", { enumerable: true, get: function () { return isIPv4_1.isIPv4; } });
16
18
  var isHexColor_1 = require("./isHexColor");
17
19
  Object.defineProperty(exports, "isHexColor", { enumerable: true, get: function () { return isHexColor_1.isHexColor; } });
20
+ var isPalindrome_1 = require("./isPalindrome");
21
+ Object.defineProperty(exports, "isPalindrome", { enumerable: true, get: function () { return isPalindrome_1.isPalindrome; } });
22
+ const isCoordinates_2 = require("./isCoordinates");
18
23
  const isDate_2 = require("./isDate");
19
24
  const isEmail_2 = require("./isEmail");
20
25
  const isEmpty_2 = require("./isEmpty");
@@ -22,12 +27,15 @@ const isSlug_2 = require("./isSlug");
22
27
  const isURL_2 = require("./isURL");
23
28
  const isIPv4_2 = require("./isIPv4");
24
29
  const isHexColor_2 = require("./isHexColor");
30
+ const isPalindrome_2 = require("./isPalindrome");
25
31
  exports.validations = {
32
+ isCoordinates: isCoordinates_2.isCoordinates,
26
33
  isDate: isDate_2.isDate,
27
34
  isEmail: isEmail_2.isEmail,
28
35
  isEmpty: isEmpty_2.isEmpty,
29
36
  isSlug: isSlug_2.isSlug,
30
37
  isURL: isURL_2.isURL,
31
38
  isIPv4: isIPv4_2.isIPv4,
32
- isHexColor: isHexColor_2.isHexColor
39
+ isHexColor: isHexColor_2.isHexColor,
40
+ isPalindrome: isPalindrome_2.isPalindrome
33
41
  };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Checks if given latitude and longitude are valid coordinates.
3
+ *
4
+ * @param {number} lat - The latitude to check.
5
+ * @param {number} long - The longitude to check.
6
+ * @returns {boolean} True if both latitude and longitude are valid, false otherwise.
7
+ */
8
+ export declare function isCoordinates(lat: number, long: number): boolean;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * Checks if given latitude and longitude are valid coordinates.
4
+ *
5
+ * @param {number} lat - The latitude to check.
6
+ * @param {number} long - The longitude to check.
7
+ * @returns {boolean} True if both latitude and longitude are valid, false otherwise.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.isCoordinates = isCoordinates;
11
+ function isCoordinates(lat, long) {
12
+ return isLatitude(lat) && isLongitude(long);
13
+ }
14
+ function isLatitude(num) {
15
+ return Number.isFinite(num) && Math.abs(num) <= 90;
16
+ }
17
+ function isLongitude(num) {
18
+ return Number.isFinite(num) && Math.abs(num) <= 180;
19
+ }
@@ -4,7 +4,7 @@ export declare enum DateFormats {
4
4
  DDMMYYYY = "DDMMYYYY"
5
5
  }
6
6
  declare const VALID_SEPARATORS: readonly [".", "-", "/"];
7
- type ValidSeparators = typeof VALID_SEPARATORS[number];
7
+ type ValidSeparators = (typeof VALID_SEPARATORS)[number];
8
8
  /**
9
9
  * Takes a date and a format and returns whether or not the date matches the specified format.
10
10
  * Optionally takes a separator that can be used instead of the default hyphen.
@@ -19,7 +19,7 @@ const VALID_SEPARATORS = ['.', '-', '/'];
19
19
  * @example 01-01-00 -> False
20
20
  */
21
21
  function isDate(input, format, separator = '-') {
22
- if (typeof input !== "string")
22
+ if (typeof input !== 'string')
23
23
  return false;
24
24
  if (input.length !== 10)
25
25
  return false;
@@ -31,22 +31,22 @@ function isDate(input, format, separator = '-') {
31
31
  // Format: YYYY-MM-DD
32
32
  format: DateFormats.YYYYMMDD,
33
33
  regex: new RegExp(`^\\d{4}${separator}\\d{2}${separator}\\d{2}$`),
34
- order: ["Y", "M", "D"],
34
+ order: ['Y', 'M', 'D'],
35
35
  },
36
36
  {
37
37
  // Format: MM-DD-YYYY
38
38
  format: DateFormats.MMDDYYYY,
39
39
  regex: new RegExp(`^\d{2}${separator}\d{2}${separator}\d{4}$/`),
40
- order: ["M", "D", "Y"],
40
+ order: ['M', 'D', 'Y'],
41
41
  },
42
42
  {
43
43
  // Format: DD-MM-YYYY
44
44
  format: DateFormats.DDMMYYYY,
45
45
  regex: new RegExp(`^\d{2}${separator}\d{2}${separator}\d{4}$`),
46
- order: ["D", "M", "Y"],
46
+ order: ['D', 'M', 'Y'],
47
47
  },
48
48
  ];
49
- const targetFormat = formats.find(f => f.format === format);
49
+ const targetFormat = formats.find((f) => f.format === format);
50
50
  const parts = input.split(separator).map(Number);
51
51
  const dateParts = {};
52
52
  targetFormat === null || targetFormat === void 0 ? void 0 : targetFormat.order.forEach((k, i) => {
@@ -56,8 +56,6 @@ function isDate(input, format, separator = '-') {
56
56
  const checkDate = new Date(Y, M - 1, D); // Months are 0 indexed
57
57
  if (checkDate.toString() === 'Invalid Date')
58
58
  return false;
59
- const isValid = checkDate.getFullYear() === Y &&
60
- checkDate.getMonth() === M - 1 &&
61
- checkDate.getDate() === D;
59
+ const isValid = checkDate.getFullYear() === Y && checkDate.getMonth() === M - 1 && checkDate.getDate() === D;
62
60
  return isValid;
63
61
  }
@@ -1 +1,13 @@
1
- export declare function isEmail(str: string): boolean;
1
+ /**
2
+ * Checks if a given string is a valid email address.
3
+ *
4
+ * Uses a regular expression to verify the format: it must contain
5
+ * one "@" symbol, no spaces, and at least one dot after the "@"
6
+ * (e.g., "example@domain.com").
7
+ *
8
+ * @param {string} str - The string to be checked.
9
+ * @returns {boolean} True if the string is a valid email address, false otherwise.
10
+ */
11
+ export declare function isEmail(str: string, opts?: {
12
+ smtpUTF8?: boolean;
13
+ }): boolean;
@@ -1,7 +1,180 @@
1
1
  "use strict";
2
+ /**
3
+ * Checks if a given string is a valid email address.
4
+ *
5
+ * Uses a regular expression to verify the format: it must contain
6
+ * one "@" symbol, no spaces, and at least one dot after the "@"
7
+ * (e.g., "example@domain.com").
8
+ *
9
+ * @param {string} str - The string to be checked.
10
+ * @returns {boolean} True if the string is a valid email address, false otherwise.
11
+ */
2
12
  Object.defineProperty(exports, "__esModule", { value: true });
3
13
  exports.isEmail = isEmail;
4
- function isEmail(str) {
5
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
6
- return emailRegex.test(str);
14
+ function isEmail(str, opts) {
15
+ if (typeof str !== 'string')
16
+ return false;
17
+ if (!str)
18
+ return false;
19
+ // Enable SMTPUTF8 by default; set opts.smtpUTF8=false to enforce ASCII-only
20
+ const smtpUTF8 = (opts === null || opts === void 0 ? void 0 : opts.smtpUTF8) !== false;
21
+ // Quick overall length guard
22
+ if (str.length > 254)
23
+ return false;
24
+ // Find the separator '@' by scanning from right to left and skipping those inside quotes
25
+ let inQuote = false;
26
+ let atIndex = -1;
27
+ for (let i = str.length - 1; i >= 0; i--) {
28
+ const ch = str[i];
29
+ if (ch === '"') {
30
+ // toggle quote state if this quote is not escaped by a backslash
31
+ const prev = str[i - 1];
32
+ if (prev !== '\\')
33
+ inQuote = !inQuote;
34
+ continue;
35
+ }
36
+ if (ch === '@' && !inQuote) {
37
+ atIndex = i;
38
+ break;
39
+ }
40
+ }
41
+ if (inQuote)
42
+ return false; // unbalanced quotes
43
+ if (atIndex <= 0 || atIndex === str.length - 1)
44
+ return false;
45
+ const local = str.slice(0, atIndex);
46
+ const domain = str.slice(atIndex + 1);
47
+ // Local-part length limit (64 octets)
48
+ if (local.length > 64)
49
+ return false;
50
+ // Validate local part as dot-separated of atoms or quoted-strings
51
+ // Validate local with a robust FSM that supports nested unescaped quotes inside quoted strings
52
+ const isAsciiAtext = (ch) => /[A-Za-z0-9!#$%&'*+\/=?^_`{|}~-]/.test(ch);
53
+ const isUnicodeAtext = (ch) => {
54
+ if (!smtpUTF8)
55
+ return false;
56
+ // Disallow obvious separators and specials used by the parser
57
+ if (ch === '.' || ch === ' ' || ch === '"' || ch === '\\' || ch === '@')
58
+ return false;
59
+ // Disallow whitespace/control
60
+ if (/\s/u.test(ch))
61
+ return false;
62
+ // Allow Unicode Letters, Marks, Numbers and Symbols (e.g., emoji)
63
+ return /[\p{L}\p{N}\p{M}\p{S}]/u.test(ch);
64
+ };
65
+ let lastWasDot = false; // disallow consecutive or leading/trailing dots anywhere
66
+ let inQ = false; // inside a quoted token
67
+ let qDepth = 0; // quote nesting depth (>=1 when inside outer quotes)
68
+ let escQ = false; // backslash escape inside quotes
69
+ let needDotAfterQuoted = false; // require a dot right after a quoted token if not at end
70
+ for (let i = 0; i < local.length; i++) {
71
+ const c = local[i];
72
+ // If we just closed a quoted token, the very next char must be a dot
73
+ if (!inQ && needDotAfterQuoted) {
74
+ if (c !== '.')
75
+ return false;
76
+ needDotAfterQuoted = false;
77
+ lastWasDot = true;
78
+ continue;
79
+ }
80
+ if (inQ) {
81
+ if (escQ) {
82
+ // After a backslash, allow any non-newline character (broader under SMTPUTF8)
83
+ if (/\r|\n/.test(c))
84
+ return false;
85
+ escQ = false;
86
+ continue;
87
+ }
88
+ if (c === '\\') {
89
+ escQ = true;
90
+ continue;
91
+ }
92
+ if (c === '"') {
93
+ // Support nested unescaped quotes within a quoted token.
94
+ // Only close the quoted token when depth returns to 0 and we're at end-of-local
95
+ // or the next character is a dot (separator between tokens).
96
+ if (qDepth > 1) {
97
+ qDepth -= 1;
98
+ lastWasDot = false;
99
+ continue;
100
+ }
101
+ // qDepth === 1: decide whether to close or to start nesting
102
+ if (i + 1 === local.length || local[i + 1] === '.') {
103
+ // this quote closes the quoted token
104
+ inQ = false;
105
+ qDepth = 0;
106
+ // require a dot if not at end
107
+ if (i + 1 < local.length)
108
+ needDotAfterQuoted = true;
109
+ lastWasDot = false;
110
+ continue;
111
+ }
112
+ else {
113
+ // start a nested quote level
114
+ qDepth += 1; // becomes 2
115
+ lastWasDot = false;
116
+ continue;
117
+ }
118
+ }
119
+ // Inside quotes: allow ASCII VCHAR and space by default; with SMTPUTF8 allow any char except control newlines
120
+ if (smtpUTF8) {
121
+ if (/\r|\n/.test(c))
122
+ return false;
123
+ }
124
+ else {
125
+ const code = c.charCodeAt(0);
126
+ if (code < 0x20 || code > 0x7E)
127
+ return false;
128
+ }
129
+ // Dots inside quoted string are allowed freely
130
+ continue;
131
+ }
132
+ // outside quotes
133
+ if (c === '"') {
134
+ // quotes can only start at token boundaries (start or right after a dot)
135
+ if (i > 0 && !lastWasDot)
136
+ return false;
137
+ inQ = true;
138
+ qDepth = 1;
139
+ escQ = false;
140
+ lastWasDot = false;
141
+ continue;
142
+ }
143
+ if (c === '.') {
144
+ if (i === 0 || lastWasDot)
145
+ return false; // leading or consecutive dot
146
+ lastWasDot = true;
147
+ continue;
148
+ }
149
+ if (c === ' ')
150
+ return false; // no spaces outside quotes
151
+ // must be atext outside quotes
152
+ if (!(isAsciiAtext(c) || isUnicodeAtext(c)))
153
+ return false;
154
+ lastWasDot = false;
155
+ }
156
+ if (inQ || qDepth !== 0 || escQ)
157
+ return false; // unbalanced quotes or dangling escape
158
+ if (lastWasDot)
159
+ return false; // trailing dot
160
+ // Validate domain
161
+ const labelRe = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/;
162
+ const ipv4Re = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;
163
+ const ipv6Re = /^IPv6:(?:[A-Fa-f0-9:]+)$/; // coarse check; detailed covered by overall tests
164
+ if (domain.startsWith('[') && domain.endsWith(']')) {
165
+ const literal = domain.slice(1, -1);
166
+ if (ipv4Re.test(literal))
167
+ return true;
168
+ if (ipv6Re.test(literal))
169
+ return true; // accept canonical IPv6 forms used in tests
170
+ return false;
171
+ }
172
+ const parts = domain.split('.');
173
+ if (parts.some(p => p.length === 0))
174
+ return false;
175
+ for (const p of parts) {
176
+ if (!labelRe.test(p))
177
+ return false;
178
+ }
179
+ return true;
7
180
  }
@@ -1 +1,10 @@
1
+ /**
2
+ * Checks whether a given string is empty or consists only of whitespace.
3
+ *
4
+ * Trims the input string and returns true if the resulting length is 0,
5
+ * indicating that the string is either empty or contains only whitespace characters.
6
+ *
7
+ * @param {string} str - The string to check.
8
+ * @returns {boolean} True if the string is empty or whitespace only, false otherwise.
9
+ */
1
10
  export declare function isEmpty(str: string): boolean;
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ /**
3
+ * Checks whether a given string is empty or consists only of whitespace.
4
+ *
5
+ * Trims the input string and returns true if the resulting length is 0,
6
+ * indicating that the string is either empty or contains only whitespace characters.
7
+ *
8
+ * @param {string} str - The string to check.
9
+ * @returns {boolean} True if the string is empty or whitespace only, false otherwise.
10
+ */
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.isEmpty = isEmpty;
4
13
  function isEmpty(str) {
@@ -8,7 +8,7 @@ exports.isHexColor = isHexColor;
8
8
  * @returns True if the string is a valid hex color, false otherwise.
9
9
  */
10
10
  function isHexColor(text) {
11
- if (typeof text !== "string" || text.length === 0) {
11
+ if (typeof text !== 'string' || text.length === 0) {
12
12
  return false;
13
13
  }
14
14
  return /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(text.trim());
@@ -1 +1,22 @@
1
+ /**
2
+ * Checks if a given string is a valid IPv4 address.
3
+ *
4
+ * Valid IPv4 addresses consist of four decimal numbers (0-255) separated by dots.
5
+ * Leading zeros are not allowed (e.g., "01" is invalid).
6
+ *
7
+ * @param {string} str - The string to validate as an IPv4 address.
8
+ * @returns {boolean} `true` if the string is a valid IPv4 address, otherwise `false`.
9
+ *
10
+ * @example
11
+ * isIPv4("192.168.1.1"); // true
12
+ *
13
+ * @example
14
+ * isIPv4("255.255.255.255"); // true
15
+ *
16
+ * @example
17
+ * isIPv4("256.100.50.0"); // false (256 is out of range)
18
+ *
19
+ * @example
20
+ * isIPv4("192.168.1"); // false (not enough parts)
21
+ */
1
22
  export declare function isIPv4(str: string): boolean;
@@ -1,13 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isIPv4 = isIPv4;
4
+ /**
5
+ * Checks if a given string is a valid IPv4 address.
6
+ *
7
+ * Valid IPv4 addresses consist of four decimal numbers (0-255) separated by dots.
8
+ * Leading zeros are not allowed (e.g., "01" is invalid).
9
+ *
10
+ * @param {string} str - The string to validate as an IPv4 address.
11
+ * @returns {boolean} `true` if the string is a valid IPv4 address, otherwise `false`.
12
+ *
13
+ * @example
14
+ * isIPv4("192.168.1.1"); // true
15
+ *
16
+ * @example
17
+ * isIPv4("255.255.255.255"); // true
18
+ *
19
+ * @example
20
+ * isIPv4("256.100.50.0"); // false (256 is out of range)
21
+ *
22
+ * @example
23
+ * isIPv4("192.168.1"); // false (not enough parts)
24
+ */
4
25
  function isIPv4(str) {
5
26
  const parts = str.split('.');
6
27
  if (parts.length !== 4)
7
28
  return false;
8
- return parts.every(part => {
29
+ return parts.every((part) => {
9
30
  const num = parseInt(part, 10);
10
31
  return !isNaN(num) && num >= 0 && num <= 255 && part === num.toString();
11
32
  });
12
33
  }
13
- ;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Checks whether the given string is a palindrome.
3
+ *
4
+ * The check is case-insensitive and ignores all non-alphanumeric characters.
5
+ *
6
+ * @param {string} str - The input string to check.
7
+ * @returns {boolean} True if the input is a palindrome, false otherwise.
8
+ * @throws {TypeError} If the input is not a string.
9
+ */
10
+ export declare function isPalindrome(str: string): boolean;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPalindrome = isPalindrome;
4
+ /**
5
+ * Checks whether the given string is a palindrome.
6
+ *
7
+ * The check is case-insensitive and ignores all non-alphanumeric characters.
8
+ *
9
+ * @param {string} str - The input string to check.
10
+ * @returns {boolean} True if the input is a palindrome, false otherwise.
11
+ * @throws {TypeError} If the input is not a string.
12
+ */
13
+ function isPalindrome(str) {
14
+ if (typeof str !== 'string') {
15
+ throw new TypeError('Input must be a string');
16
+ }
17
+ const sanitized = str
18
+ .toLowerCase()
19
+ .replace(/[^a-z0-9]/gi, '');
20
+ return sanitized === sanitized.split('').reverse().join('');
21
+ }
@@ -1 +1,28 @@
1
+ /**
2
+ * Checks if a given string is a valid slug.
3
+ *
4
+ * A valid slug:
5
+ * - Contains only lowercase letters (`a-z`), numbers (`0-9`), and hyphens (`-`).
6
+ * - Does not start or end with a hyphen.
7
+ * - Does not contain consecutive hyphens.
8
+ * - Is not an empty string.
9
+ *
10
+ * @param {string} str - The string to validate as a slug.
11
+ * @returns {boolean} `true` if the string is a valid slug, otherwise `false`.
12
+ *
13
+ * @example
14
+ * isSlug("valid-slug-123"); // true
15
+ *
16
+ * @example
17
+ * isSlug("Invalid-Slug"); // false (uppercase letters)
18
+ *
19
+ * @example
20
+ * isSlug("-starts-with-hyphen"); // false
21
+ *
22
+ * @example
23
+ * isSlug("ends-with-hyphen-"); // false
24
+ *
25
+ * @example
26
+ * isSlug("double--hyphen"); // false
27
+ */
1
28
  export declare function isSlug(str: string): boolean;
@@ -1,6 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isSlug = isSlug;
4
+ /**
5
+ * Checks if a given string is a valid slug.
6
+ *
7
+ * A valid slug:
8
+ * - Contains only lowercase letters (`a-z`), numbers (`0-9`), and hyphens (`-`).
9
+ * - Does not start or end with a hyphen.
10
+ * - Does not contain consecutive hyphens.
11
+ * - Is not an empty string.
12
+ *
13
+ * @param {string} str - The string to validate as a slug.
14
+ * @returns {boolean} `true` if the string is a valid slug, otherwise `false`.
15
+ *
16
+ * @example
17
+ * isSlug("valid-slug-123"); // true
18
+ *
19
+ * @example
20
+ * isSlug("Invalid-Slug"); // false (uppercase letters)
21
+ *
22
+ * @example
23
+ * isSlug("-starts-with-hyphen"); // false
24
+ *
25
+ * @example
26
+ * isSlug("ends-with-hyphen-"); // false
27
+ *
28
+ * @example
29
+ * isSlug("double--hyphen"); // false
30
+ */
4
31
  function isSlug(str) {
5
32
  if (typeof str !== 'string' || str.length === 0) {
6
33
  return false;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Checks if a file name or URL string has a valid extension for a given type.
3
+ *
4
+ * @param {string} input - File name or URL.
5
+ * @param {string} type - The type category to validate.
6
+ * @returns {boolean}
7
+ * @throws error when input is not string or type is not defined
8
+ */
9
+ export declare function isTypeOf(input: string, type: string): boolean;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTypeOf = isTypeOf;
4
+ /**
5
+ * Checks if a file name or URL string has a valid extension for a given type.
6
+ *
7
+ * @param {string} input - File name or URL.
8
+ * @param {string} type - The type category to validate.
9
+ * @returns {boolean}
10
+ * @throws error when input is not string or type is not defined
11
+ */
12
+ function isTypeOf(input, type) {
13
+ var _a;
14
+ if (typeof input !== "string" || typeof type !== "string")
15
+ return false;
16
+ // Gets the substring after the last (.), then converts to lowercase, removes (?) and (#)
17
+ // Example: "image.png?version=2#top", returns "png"
18
+ const extension = (_a = input.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase().split("?")[0].split("#")[0];
19
+ if (!extension)
20
+ return false;
21
+ const typeMap = {
22
+ image: ["png", "jpg", "jpeg", "gif", "bmp", "svg", "webp", "ico"],
23
+ video: ["mp4", "webm", "avi", "mkv", "mov", "flv"],
24
+ audio: ["mp3", "wav", "ogg", "flac", "aac"],
25
+ document: ["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "md"],
26
+ archive: ["zip", "rar", "tar", "gz", "7z"],
27
+ };
28
+ const allowed = typeMap[type.toLowerCase()];
29
+ return allowed ? allowed.includes(extension) : false;
30
+ }
@@ -1 +1,22 @@
1
+ /**
2
+ * Checks if a given string is a valid URL.
3
+ *
4
+ * Uses the built-in `URL` constructor to attempt parsing the input string.
5
+ * Returns `true` if the string is a valid URL, otherwise `false`.
6
+ *
7
+ * @param {string} str - The string to validate as a URL.
8
+ * @returns {boolean} `true` if the string is a valid URL, otherwise `false`.
9
+ *
10
+ * @example
11
+ * isURL("https://www.example.com"); // true
12
+ *
13
+ * @example
14
+ * isURL("ftp://ftp.example.com/resource.txt"); // true
15
+ *
16
+ * @example
17
+ * isURL("not a url"); // false
18
+ *
19
+ * @example
20
+ * isURL("http:/invalid-url"); // false
21
+ */
1
22
  export declare function isURL(str: string): boolean;
@@ -1,6 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isURL = isURL;
4
+ /**
5
+ * Checks if a given string is a valid URL.
6
+ *
7
+ * Uses the built-in `URL` constructor to attempt parsing the input string.
8
+ * Returns `true` if the string is a valid URL, otherwise `false`.
9
+ *
10
+ * @param {string} str - The string to validate as a URL.
11
+ * @returns {boolean} `true` if the string is a valid URL, otherwise `false`.
12
+ *
13
+ * @example
14
+ * isURL("https://www.example.com"); // true
15
+ *
16
+ * @example
17
+ * isURL("ftp://ftp.example.com/resource.txt"); // true
18
+ *
19
+ * @example
20
+ * isURL("not a url"); // false
21
+ *
22
+ * @example
23
+ * isURL("http:/invalid-url"); // false
24
+ */
4
25
  function isURL(str) {
5
26
  try {
6
27
  new URL(str);
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "stringzy",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
7
7
  "build": "tsc",
8
8
  "test": "npm run build && node --test",
9
- "prepublishOnly": "npm run build"
9
+ "prepublishOnly": "npm run build",
10
+ "format": "prettier --write ."
10
11
  },
11
12
  "author": "Samarth Ruia",
12
13
  "readmeFilename": "README.md",
@@ -44,7 +45,8 @@
44
45
  "url": "git+https://github.com/Samarth2190/stringzy.git"
45
46
  },
46
47
  "devDependencies": {
47
- "@types/node": "^24.0.0",
48
+ "@types/node": "^24.0.4",
49
+ "prettier": "^3.6.2",
48
50
  "typescript": "^5.8.3"
49
51
  }
50
52
  }