@itshackers/utilix 0.0.0-stage → 0.3.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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +304 -3
  3. package/dist/common/index.cjs +102 -0
  4. package/dist/common/index.cjs.map +1 -0
  5. package/dist/common/index.d.cts +58 -0
  6. package/dist/common/index.d.ts +58 -0
  7. package/dist/common/index.js +93 -0
  8. package/dist/common/index.js.map +1 -0
  9. package/dist/date/index.cjs +154 -0
  10. package/dist/date/index.cjs.map +1 -0
  11. package/dist/date/index.d.cts +65 -0
  12. package/dist/date/index.d.ts +65 -0
  13. package/dist/date/index.js +146 -0
  14. package/dist/date/index.js.map +1 -0
  15. package/dist/format/index.cjs +136 -0
  16. package/dist/format/index.cjs.map +1 -0
  17. package/dist/format/index.d.cts +56 -0
  18. package/dist/format/index.d.ts +56 -0
  19. package/dist/format/index.js +130 -0
  20. package/dist/format/index.js.map +1 -0
  21. package/dist/id/index.cjs +66 -0
  22. package/dist/id/index.cjs.map +1 -0
  23. package/dist/id/index.d.cts +19 -0
  24. package/dist/id/index.d.ts +19 -0
  25. package/dist/id/index.js +64 -0
  26. package/dist/id/index.js.map +1 -0
  27. package/dist/index.cjs +906 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +12 -0
  30. package/dist/index.d.ts +12 -0
  31. package/dist/index.js +853 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/number/index.cjs +107 -0
  34. package/dist/number/index.cjs.map +1 -0
  35. package/dist/number/index.d.cts +90 -0
  36. package/dist/number/index.d.ts +90 -0
  37. package/dist/number/index.js +99 -0
  38. package/dist/number/index.js.map +1 -0
  39. package/dist/password/index.cjs +71 -0
  40. package/dist/password/index.cjs.map +1 -0
  41. package/dist/password/index.d.cts +15 -0
  42. package/dist/password/index.d.ts +15 -0
  43. package/dist/password/index.js +69 -0
  44. package/dist/password/index.js.map +1 -0
  45. package/dist/phone/index.cjs +19 -0
  46. package/dist/phone/index.cjs.map +1 -0
  47. package/dist/phone/index.d.cts +12 -0
  48. package/dist/phone/index.d.ts +12 -0
  49. package/dist/phone/index.js +17 -0
  50. package/dist/phone/index.js.map +1 -0
  51. package/dist/regex/index.cjs +73 -0
  52. package/dist/regex/index.cjs.map +1 -0
  53. package/dist/regex/index.d.cts +65 -0
  54. package/dist/regex/index.d.ts +65 -0
  55. package/dist/regex/index.js +67 -0
  56. package/dist/regex/index.js.map +1 -0
  57. package/dist/response/index.cjs +43 -0
  58. package/dist/response/index.cjs.map +1 -0
  59. package/dist/response/index.d.cts +41 -0
  60. package/dist/response/index.d.ts +41 -0
  61. package/dist/response/index.js +40 -0
  62. package/dist/response/index.js.map +1 -0
  63. package/dist/sanitize/index.cjs +83 -0
  64. package/dist/sanitize/index.cjs.map +1 -0
  65. package/dist/sanitize/index.d.cts +20 -0
  66. package/dist/sanitize/index.d.ts +20 -0
  67. package/dist/sanitize/index.js +80 -0
  68. package/dist/sanitize/index.js.map +1 -0
  69. package/dist/slug/index.cjs +33 -0
  70. package/dist/slug/index.cjs.map +1 -0
  71. package/dist/slug/index.d.cts +38 -0
  72. package/dist/slug/index.d.ts +38 -0
  73. package/dist/slug/index.js +31 -0
  74. package/dist/slug/index.js.map +1 -0
  75. package/dist/string/index.cjs +130 -0
  76. package/dist/string/index.cjs.map +1 -0
  77. package/dist/string/index.d.cts +112 -0
  78. package/dist/string/index.d.ts +112 -0
  79. package/dist/string/index.js +115 -0
  80. package/dist/string/index.js.map +1 -0
  81. package/package.json +187 -3
@@ -0,0 +1,130 @@
1
+ 'use strict';
2
+
3
+ // src/internal/validation.ts
4
+ function escapeRegExp(value) {
5
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6
+ }
7
+
8
+ // src/string/index.ts
9
+ var HTML_ESCAPE_MAP = {
10
+ "&": "&",
11
+ "<": "&lt;",
12
+ ">": "&gt;",
13
+ '"': "&quot;",
14
+ "'": "&#39;"
15
+ };
16
+ function splitWords(value) {
17
+ const trimmed = value.trim();
18
+ if (trimmed.length === 0) {
19
+ return [];
20
+ }
21
+ return trimmed.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(/[\s._-]+/u).filter((word) => word.length > 0);
22
+ }
23
+ function toLowerWords(value) {
24
+ return splitWords(value).map((word) => word.toLowerCase());
25
+ }
26
+ function capitalizeWord(word) {
27
+ const [first = "", ...rest] = [...word];
28
+ return `${first.toUpperCase()}${rest.join("").toLowerCase()}`;
29
+ }
30
+ function toCamelCase(value) {
31
+ const words = toLowerWords(value);
32
+ if (words.length === 0) {
33
+ return "";
34
+ }
35
+ const [first = "", ...rest] = words;
36
+ return `${first}${rest.map(capitalizeWord).join("")}`;
37
+ }
38
+ function toPascalCase(value) {
39
+ return toLowerWords(value).map(capitalizeWord).join("");
40
+ }
41
+ function toSnakeCase(value) {
42
+ return toLowerWords(value).join("_");
43
+ }
44
+ function toKebabCase(value) {
45
+ return toLowerWords(value).join("-");
46
+ }
47
+ function capitalize(value) {
48
+ const trimmed = value.trim();
49
+ if (trimmed.length === 0) {
50
+ return "";
51
+ }
52
+ const [first = "", ...rest] = [...trimmed];
53
+ return `${first.toUpperCase()}${rest.join("")}`;
54
+ }
55
+ function normalizeWhitespace(value) {
56
+ return value.trim().replace(/\s+/gu, " ");
57
+ }
58
+ function escapeHtml(value) {
59
+ return value.replace(/[&<>"']/g, (character) => HTML_ESCAPE_MAP[character] ?? character);
60
+ }
61
+ function escapeRegex(value) {
62
+ return escapeRegExp(value);
63
+ }
64
+ function toTitleCase(value) {
65
+ const trimmed = value.trim();
66
+ if (trimmed.length === 0) {
67
+ return "";
68
+ }
69
+ return trimmed.toLowerCase().replace(/\b\w/g, (character) => character.toUpperCase());
70
+ }
71
+ function convertCase(value, casing = "title") {
72
+ switch (casing.toLowerCase()) {
73
+ case "title":
74
+ case "titlecase":
75
+ return toTitleCase(value);
76
+ case "lower":
77
+ case "lowercase":
78
+ return value.trim().toLowerCase();
79
+ case "upper":
80
+ case "uppercase":
81
+ return value.trim().toUpperCase();
82
+ case "camel":
83
+ case "camelcase":
84
+ return toCamelCase(value);
85
+ case "pascal":
86
+ case "pascalcase":
87
+ return toPascalCase(value);
88
+ case "snake":
89
+ case "snakecase":
90
+ return toSnakeCase(value);
91
+ case "kebab":
92
+ case "kebabcase":
93
+ return toKebabCase(value);
94
+ default:
95
+ throw new TypeError(`Unsupported case style: ${casing}`);
96
+ }
97
+ }
98
+ function replaceSeparatorsWithSpace(value) {
99
+ return toTitleCase(value.replace(/[-_]+/g, " ").replace(/\s+/g, " "));
100
+ }
101
+ function htmlToPlainText(value) {
102
+ if (value.trim().length === 0) {
103
+ return "";
104
+ }
105
+ return value.replace(/<(br|\/p|\/div|\/pre|\/li)\b[^>]*>/gi, " ").replace(/<[^>]*>/g, " ").replace(/[\n\t]+/g, " ").replace(/\s+/g, " ").trim();
106
+ }
107
+ function nonEmptyString(value) {
108
+ if (typeof value !== "string") {
109
+ return null;
110
+ }
111
+ const trimmed = value.trim();
112
+ return trimmed.length === 0 ? null : trimmed;
113
+ }
114
+
115
+ exports.capitalize = capitalize;
116
+ exports.convertCase = convertCase;
117
+ exports.escapeHtml = escapeHtml;
118
+ exports.escapeRegExp = escapeRegex;
119
+ exports.escapeRegex = escapeRegex;
120
+ exports.htmlToPlainText = htmlToPlainText;
121
+ exports.nonEmptyString = nonEmptyString;
122
+ exports.normalizeWhitespace = normalizeWhitespace;
123
+ exports.replaceSeparatorsWithSpace = replaceSeparatorsWithSpace;
124
+ exports.toCamelCase = toCamelCase;
125
+ exports.toKebabCase = toKebabCase;
126
+ exports.toPascalCase = toPascalCase;
127
+ exports.toSnakeCase = toSnakeCase;
128
+ exports.toTitleCase = toTitleCase;
129
+ //# sourceMappingURL=index.cjs.map
130
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/internal/validation.ts","../../src/string/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export function assertFiniteNumber(\r\n value: unknown,\r\n name: string,\r\n): asserts value is number {\r\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\r\n throw new TypeError(`${name} must be a finite number`);\r\n }\r\n}\r\n\r\nexport function escapeRegExp(value: string): string {\r\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n","import { escapeRegExp } from \"../internal/validation.js\";\r\n\r\nexport type TextCase =\r\n | \"title\"\r\n | \"titlecase\"\r\n | \"lower\"\r\n | \"lowercase\"\r\n | \"upper\"\r\n | \"uppercase\"\r\n | \"camel\"\r\n | \"camelcase\"\r\n | \"pascal\"\r\n | \"pascalcase\"\r\n | \"snake\"\r\n | \"snakecase\"\r\n | \"kebab\"\r\n | \"kebabcase\";\r\n\r\nconst HTML_ESCAPE_MAP: Record<string, string> = {\r\n \"&\": \"&amp;\",\r\n \"<\": \"&lt;\",\r\n \">\": \"&gt;\",\r\n '\"': \"&quot;\",\r\n \"'\": \"&#39;\",\r\n};\r\n\r\n/**\r\n * Splits mixed naming conventions into discrete words.\r\n * Handles spaces, hyphens, underscores, dots, and camel/PascalCase boundaries.\r\n */\r\nfunction splitWords(value: string): string[] {\r\n const trimmed = value.trim();\r\n if (trimmed.length === 0) {\r\n return [];\r\n }\r\n\r\n return trimmed\r\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\r\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\r\n .split(/[\\s._-]+/u)\r\n .filter((word) => word.length > 0);\r\n}\r\n\r\nfunction toLowerWords(value: string): string[] {\r\n return splitWords(value).map((word) => word.toLowerCase());\r\n}\r\n\r\nfunction capitalizeWord(word: string): string {\r\n const [first = \"\", ...rest] = [...word];\r\n return `${first.toUpperCase()}${rest.join(\"\").toLowerCase()}`;\r\n}\r\n\r\n/**\r\n * Converts a string to camelCase.\r\n *\r\n * @example\r\n * toCamelCase(\"hello-world\") // \"helloWorld\"\r\n * toCamelCase(\"XMLHttpRequest\") // \"xmlHttpRequest\"\r\n */\r\nexport function toCamelCase(value: string): string {\r\n const words = toLowerWords(value);\r\n if (words.length === 0) {\r\n return \"\";\r\n }\r\n\r\n const [first = \"\", ...rest] = words;\r\n return `${first}${rest.map(capitalizeWord).join(\"\")}`;\r\n}\r\n\r\n/**\r\n * Converts a string to PascalCase.\r\n *\r\n * @example\r\n * toPascalCase(\"hello_world\") // \"HelloWorld\"\r\n */\r\nexport function toPascalCase(value: string): string {\r\n return toLowerWords(value).map(capitalizeWord).join(\"\");\r\n}\r\n\r\n/**\r\n * Converts a string to snake_case.\r\n *\r\n * @example\r\n * toSnakeCase(\"Hello World\") // \"hello_world\"\r\n */\r\nexport function toSnakeCase(value: string): string {\r\n return toLowerWords(value).join(\"_\");\r\n}\r\n\r\n/**\r\n * Converts a string to kebab-case.\r\n *\r\n * @example\r\n * toKebabCase(\"HelloWorld\") // \"hello-world\"\r\n */\r\nexport function toKebabCase(value: string): string {\r\n return toLowerWords(value).join(\"-\");\r\n}\r\n\r\n/**\r\n * Trims the string and uppercases its first Unicode character.\r\n * The remaining characters are left unchanged.\r\n *\r\n * @example\r\n * capitalize(\" hello world\") // \"Hello world\"\r\n */\r\nexport function capitalize(value: string): string {\r\n const trimmed = value.trim();\r\n if (trimmed.length === 0) {\r\n return \"\";\r\n }\r\n\r\n const [first = \"\", ...rest] = [...trimmed];\r\n return `${first.toUpperCase()}${rest.join(\"\")}`;\r\n}\r\n\r\n/**\r\n * Trims leading and trailing whitespace and collapses internal\r\n * whitespace runs to a single space.\r\n *\r\n * @example\r\n * normalizeWhitespace(\" hello \\t\\n world \") // \"hello world\"\r\n */\r\nexport function normalizeWhitespace(value: string): string {\r\n return value.trim().replace(/\\s+/gu, \" \");\r\n}\r\n\r\n/**\r\n * Escapes `&`, `<`, `>`, `\"`, and `'` for safe interpolation into HTML text\r\n * or quoted attributes.\r\n *\r\n * This is not an HTML sanitizer. It does not parse markup, remove scripts,\r\n * or make untrusted HTML safe to render.\r\n *\r\n * @example\r\n * escapeHtml(`<img alt=\"O'Reilly & Co\">`)\r\n * // \"&lt;img alt=&quot;O&#39;Reilly &amp; Co&quot;&gt;\"\r\n */\r\nexport function escapeHtml(value: string): string {\r\n return value.replace(/[&<>\"']/g, (character) => HTML_ESCAPE_MAP[character] ?? character);\r\n}\r\n\r\n/**\r\n * Escapes special regular-expression characters in a string.\r\n *\r\n * @example\r\n * escapeRegex(\"file.name.txt\") // \"file\\\\.name\\\\.txt\"\r\n */\r\nexport function escapeRegex(value: string): string {\r\n return escapeRegExp(value);\r\n}\r\n\r\nexport { escapeRegex as escapeRegExp };\r\n\r\n/**\r\n * Converts a string to Title Case using word boundaries.\r\n *\r\n * @example\r\n * toTitleCase(\"hello world\") // \"Hello World\"\r\n * toTitleCase(\"used-truck\") // \"Used-Truck\"\r\n */\r\nexport function toTitleCase(value: string): string {\r\n const trimmed = value.trim();\r\n if (trimmed.length === 0) {\r\n return \"\";\r\n }\r\n\r\n return trimmed.toLowerCase().replace(/\\b\\w/g, (character) => character.toUpperCase());\r\n}\r\n\r\n/**\r\n * Converts a string to one of the supported case styles.\r\n * Unknown styles throw rather than silently falling back.\r\n *\r\n * @example\r\n * convertCase(\"hello world\", \"title\") // \"Hello World\"\r\n * convertCase(\"hello-world\", \"camel\") // \"helloWorld\"\r\n */\r\nexport function convertCase(value: string, casing: TextCase = \"title\"): string {\r\n switch (casing.toLowerCase() as TextCase) {\r\n case \"title\":\r\n case \"titlecase\":\r\n return toTitleCase(value);\r\n case \"lower\":\r\n case \"lowercase\":\r\n return value.trim().toLowerCase();\r\n case \"upper\":\r\n case \"uppercase\":\r\n return value.trim().toUpperCase();\r\n case \"camel\":\r\n case \"camelcase\":\r\n return toCamelCase(value);\r\n case \"pascal\":\r\n case \"pascalcase\":\r\n return toPascalCase(value);\r\n case \"snake\":\r\n case \"snakecase\":\r\n return toSnakeCase(value);\r\n case \"kebab\":\r\n case \"kebabcase\":\r\n return toKebabCase(value);\r\n default:\r\n throw new TypeError(`Unsupported case style: ${casing}`);\r\n }\r\n}\r\n\r\n/**\r\n * Replaces hyphens and underscores with spaces, then title-cases the result.\r\n *\r\n * @example\r\n * replaceSeparatorsWithSpace(\"used-truck\") // \"Used Truck\"\r\n * replaceSeparatorsWithSpace(\"hello_world\") // \"Hello World\"\r\n */\r\nexport function replaceSeparatorsWithSpace(value: string): string {\r\n return toTitleCase(value.replace(/[-_]+/g, \" \").replace(/\\s+/g, \" \"));\r\n}\r\n\r\n/**\r\n * Strips HTML tags and collapses whitespace into a single-line plain-text string.\r\n *\r\n * This is not an HTML sanitizer or a complete HTML parser. It does not decode\r\n * all entities or preserve document structure.\r\n *\r\n * @example\r\n * htmlToPlainText(\"<p>Hello<br>World</p>\") // \"Hello World\"\r\n */\r\nexport function htmlToPlainText(value: string): string {\r\n if (value.trim().length === 0) {\r\n return \"\";\r\n }\r\n\r\n return value\r\n .replace(/<(br|\\/p|\\/div|\\/pre|\\/li)\\b[^>]*>/gi, \" \")\r\n .replace(/<[^>]*>/g, \" \")\r\n .replace(/[\\n\\t]+/g, \" \")\r\n .replace(/\\s+/g, \" \")\r\n .trim();\r\n}\r\n\r\n/**\r\n * Returns a trimmed string, or `null` when the value is not a non-empty string.\r\n *\r\n * @example\r\n * nonEmptyString(\" Gold \") // \"Gold\"\r\n * nonEmptyString(\" \") // null\r\n */\r\nexport function nonEmptyString(value: unknown): string | null {\r\n if (typeof value !== \"string\") {\r\n return null;\r\n }\r\n\r\n const trimmed = value.trim();\r\n return trimmed.length === 0 ? null : trimmed;\r\n}\r\n"]}
@@ -0,0 +1,112 @@
1
+ type TextCase = "title" | "titlecase" | "lower" | "lowercase" | "upper" | "uppercase" | "camel" | "camelcase" | "pascal" | "pascalcase" | "snake" | "snakecase" | "kebab" | "kebabcase";
2
+ /**
3
+ * Converts a string to camelCase.
4
+ *
5
+ * @example
6
+ * toCamelCase("hello-world") // "helloWorld"
7
+ * toCamelCase("XMLHttpRequest") // "xmlHttpRequest"
8
+ */
9
+ declare function toCamelCase(value: string): string;
10
+ /**
11
+ * Converts a string to PascalCase.
12
+ *
13
+ * @example
14
+ * toPascalCase("hello_world") // "HelloWorld"
15
+ */
16
+ declare function toPascalCase(value: string): string;
17
+ /**
18
+ * Converts a string to snake_case.
19
+ *
20
+ * @example
21
+ * toSnakeCase("Hello World") // "hello_world"
22
+ */
23
+ declare function toSnakeCase(value: string): string;
24
+ /**
25
+ * Converts a string to kebab-case.
26
+ *
27
+ * @example
28
+ * toKebabCase("HelloWorld") // "hello-world"
29
+ */
30
+ declare function toKebabCase(value: string): string;
31
+ /**
32
+ * Trims the string and uppercases its first Unicode character.
33
+ * The remaining characters are left unchanged.
34
+ *
35
+ * @example
36
+ * capitalize(" hello world") // "Hello world"
37
+ */
38
+ declare function capitalize(value: string): string;
39
+ /**
40
+ * Trims leading and trailing whitespace and collapses internal
41
+ * whitespace runs to a single space.
42
+ *
43
+ * @example
44
+ * normalizeWhitespace(" hello \t\n world ") // "hello world"
45
+ */
46
+ declare function normalizeWhitespace(value: string): string;
47
+ /**
48
+ * Escapes `&`, `<`, `>`, `"`, and `'` for safe interpolation into HTML text
49
+ * or quoted attributes.
50
+ *
51
+ * This is not an HTML sanitizer. It does not parse markup, remove scripts,
52
+ * or make untrusted HTML safe to render.
53
+ *
54
+ * @example
55
+ * escapeHtml(`<img alt="O'Reilly & Co">`)
56
+ * // "&lt;img alt=&quot;O&#39;Reilly &amp; Co&quot;&gt;"
57
+ */
58
+ declare function escapeHtml(value: string): string;
59
+ /**
60
+ * Escapes special regular-expression characters in a string.
61
+ *
62
+ * @example
63
+ * escapeRegex("file.name.txt") // "file\\.name\\.txt"
64
+ */
65
+ declare function escapeRegex(value: string): string;
66
+
67
+ /**
68
+ * Converts a string to Title Case using word boundaries.
69
+ *
70
+ * @example
71
+ * toTitleCase("hello world") // "Hello World"
72
+ * toTitleCase("used-truck") // "Used-Truck"
73
+ */
74
+ declare function toTitleCase(value: string): string;
75
+ /**
76
+ * Converts a string to one of the supported case styles.
77
+ * Unknown styles throw rather than silently falling back.
78
+ *
79
+ * @example
80
+ * convertCase("hello world", "title") // "Hello World"
81
+ * convertCase("hello-world", "camel") // "helloWorld"
82
+ */
83
+ declare function convertCase(value: string, casing?: TextCase): string;
84
+ /**
85
+ * Replaces hyphens and underscores with spaces, then title-cases the result.
86
+ *
87
+ * @example
88
+ * replaceSeparatorsWithSpace("used-truck") // "Used Truck"
89
+ * replaceSeparatorsWithSpace("hello_world") // "Hello World"
90
+ */
91
+ declare function replaceSeparatorsWithSpace(value: string): string;
92
+ /**
93
+ * Strips HTML tags and collapses whitespace into a single-line plain-text string.
94
+ *
95
+ * This is not an HTML sanitizer or a complete HTML parser. It does not decode
96
+ * all entities or preserve document structure.
97
+ *
98
+ * @example
99
+ * htmlToPlainText("<p>Hello<br>World</p>") // "Hello World"
100
+ */
101
+ declare function htmlToPlainText(value: string): string;
102
+ /**
103
+ * Returns a trimmed string, or `null` when the value is not a non-empty string.
104
+ *
105
+ * @example
106
+ * nonEmptyString(" Gold ") // "Gold"
107
+ * nonEmptyString(" ") // null
108
+ */
109
+ declare function nonEmptyString(value: unknown): string | null;
110
+
111
+ export { capitalize, convertCase, escapeHtml, escapeRegex as escapeRegExp, escapeRegex, htmlToPlainText, nonEmptyString, normalizeWhitespace, replaceSeparatorsWithSpace, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, toTitleCase };
112
+ export type { TextCase };
@@ -0,0 +1,112 @@
1
+ type TextCase = "title" | "titlecase" | "lower" | "lowercase" | "upper" | "uppercase" | "camel" | "camelcase" | "pascal" | "pascalcase" | "snake" | "snakecase" | "kebab" | "kebabcase";
2
+ /**
3
+ * Converts a string to camelCase.
4
+ *
5
+ * @example
6
+ * toCamelCase("hello-world") // "helloWorld"
7
+ * toCamelCase("XMLHttpRequest") // "xmlHttpRequest"
8
+ */
9
+ declare function toCamelCase(value: string): string;
10
+ /**
11
+ * Converts a string to PascalCase.
12
+ *
13
+ * @example
14
+ * toPascalCase("hello_world") // "HelloWorld"
15
+ */
16
+ declare function toPascalCase(value: string): string;
17
+ /**
18
+ * Converts a string to snake_case.
19
+ *
20
+ * @example
21
+ * toSnakeCase("Hello World") // "hello_world"
22
+ */
23
+ declare function toSnakeCase(value: string): string;
24
+ /**
25
+ * Converts a string to kebab-case.
26
+ *
27
+ * @example
28
+ * toKebabCase("HelloWorld") // "hello-world"
29
+ */
30
+ declare function toKebabCase(value: string): string;
31
+ /**
32
+ * Trims the string and uppercases its first Unicode character.
33
+ * The remaining characters are left unchanged.
34
+ *
35
+ * @example
36
+ * capitalize(" hello world") // "Hello world"
37
+ */
38
+ declare function capitalize(value: string): string;
39
+ /**
40
+ * Trims leading and trailing whitespace and collapses internal
41
+ * whitespace runs to a single space.
42
+ *
43
+ * @example
44
+ * normalizeWhitespace(" hello \t\n world ") // "hello world"
45
+ */
46
+ declare function normalizeWhitespace(value: string): string;
47
+ /**
48
+ * Escapes `&`, `<`, `>`, `"`, and `'` for safe interpolation into HTML text
49
+ * or quoted attributes.
50
+ *
51
+ * This is not an HTML sanitizer. It does not parse markup, remove scripts,
52
+ * or make untrusted HTML safe to render.
53
+ *
54
+ * @example
55
+ * escapeHtml(`<img alt="O'Reilly & Co">`)
56
+ * // "&lt;img alt=&quot;O&#39;Reilly &amp; Co&quot;&gt;"
57
+ */
58
+ declare function escapeHtml(value: string): string;
59
+ /**
60
+ * Escapes special regular-expression characters in a string.
61
+ *
62
+ * @example
63
+ * escapeRegex("file.name.txt") // "file\\.name\\.txt"
64
+ */
65
+ declare function escapeRegex(value: string): string;
66
+
67
+ /**
68
+ * Converts a string to Title Case using word boundaries.
69
+ *
70
+ * @example
71
+ * toTitleCase("hello world") // "Hello World"
72
+ * toTitleCase("used-truck") // "Used-Truck"
73
+ */
74
+ declare function toTitleCase(value: string): string;
75
+ /**
76
+ * Converts a string to one of the supported case styles.
77
+ * Unknown styles throw rather than silently falling back.
78
+ *
79
+ * @example
80
+ * convertCase("hello world", "title") // "Hello World"
81
+ * convertCase("hello-world", "camel") // "helloWorld"
82
+ */
83
+ declare function convertCase(value: string, casing?: TextCase): string;
84
+ /**
85
+ * Replaces hyphens and underscores with spaces, then title-cases the result.
86
+ *
87
+ * @example
88
+ * replaceSeparatorsWithSpace("used-truck") // "Used Truck"
89
+ * replaceSeparatorsWithSpace("hello_world") // "Hello World"
90
+ */
91
+ declare function replaceSeparatorsWithSpace(value: string): string;
92
+ /**
93
+ * Strips HTML tags and collapses whitespace into a single-line plain-text string.
94
+ *
95
+ * This is not an HTML sanitizer or a complete HTML parser. It does not decode
96
+ * all entities or preserve document structure.
97
+ *
98
+ * @example
99
+ * htmlToPlainText("<p>Hello<br>World</p>") // "Hello World"
100
+ */
101
+ declare function htmlToPlainText(value: string): string;
102
+ /**
103
+ * Returns a trimmed string, or `null` when the value is not a non-empty string.
104
+ *
105
+ * @example
106
+ * nonEmptyString(" Gold ") // "Gold"
107
+ * nonEmptyString(" ") // null
108
+ */
109
+ declare function nonEmptyString(value: unknown): string | null;
110
+
111
+ export { capitalize, convertCase, escapeHtml, escapeRegex as escapeRegExp, escapeRegex, htmlToPlainText, nonEmptyString, normalizeWhitespace, replaceSeparatorsWithSpace, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, toTitleCase };
112
+ export type { TextCase };
@@ -0,0 +1,115 @@
1
+ // src/internal/validation.ts
2
+ function escapeRegExp(value) {
3
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4
+ }
5
+
6
+ // src/string/index.ts
7
+ var HTML_ESCAPE_MAP = {
8
+ "&": "&amp;",
9
+ "<": "&lt;",
10
+ ">": "&gt;",
11
+ '"': "&quot;",
12
+ "'": "&#39;"
13
+ };
14
+ function splitWords(value) {
15
+ const trimmed = value.trim();
16
+ if (trimmed.length === 0) {
17
+ return [];
18
+ }
19
+ return trimmed.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(/[\s._-]+/u).filter((word) => word.length > 0);
20
+ }
21
+ function toLowerWords(value) {
22
+ return splitWords(value).map((word) => word.toLowerCase());
23
+ }
24
+ function capitalizeWord(word) {
25
+ const [first = "", ...rest] = [...word];
26
+ return `${first.toUpperCase()}${rest.join("").toLowerCase()}`;
27
+ }
28
+ function toCamelCase(value) {
29
+ const words = toLowerWords(value);
30
+ if (words.length === 0) {
31
+ return "";
32
+ }
33
+ const [first = "", ...rest] = words;
34
+ return `${first}${rest.map(capitalizeWord).join("")}`;
35
+ }
36
+ function toPascalCase(value) {
37
+ return toLowerWords(value).map(capitalizeWord).join("");
38
+ }
39
+ function toSnakeCase(value) {
40
+ return toLowerWords(value).join("_");
41
+ }
42
+ function toKebabCase(value) {
43
+ return toLowerWords(value).join("-");
44
+ }
45
+ function capitalize(value) {
46
+ const trimmed = value.trim();
47
+ if (trimmed.length === 0) {
48
+ return "";
49
+ }
50
+ const [first = "", ...rest] = [...trimmed];
51
+ return `${first.toUpperCase()}${rest.join("")}`;
52
+ }
53
+ function normalizeWhitespace(value) {
54
+ return value.trim().replace(/\s+/gu, " ");
55
+ }
56
+ function escapeHtml(value) {
57
+ return value.replace(/[&<>"']/g, (character) => HTML_ESCAPE_MAP[character] ?? character);
58
+ }
59
+ function escapeRegex(value) {
60
+ return escapeRegExp(value);
61
+ }
62
+ function toTitleCase(value) {
63
+ const trimmed = value.trim();
64
+ if (trimmed.length === 0) {
65
+ return "";
66
+ }
67
+ return trimmed.toLowerCase().replace(/\b\w/g, (character) => character.toUpperCase());
68
+ }
69
+ function convertCase(value, casing = "title") {
70
+ switch (casing.toLowerCase()) {
71
+ case "title":
72
+ case "titlecase":
73
+ return toTitleCase(value);
74
+ case "lower":
75
+ case "lowercase":
76
+ return value.trim().toLowerCase();
77
+ case "upper":
78
+ case "uppercase":
79
+ return value.trim().toUpperCase();
80
+ case "camel":
81
+ case "camelcase":
82
+ return toCamelCase(value);
83
+ case "pascal":
84
+ case "pascalcase":
85
+ return toPascalCase(value);
86
+ case "snake":
87
+ case "snakecase":
88
+ return toSnakeCase(value);
89
+ case "kebab":
90
+ case "kebabcase":
91
+ return toKebabCase(value);
92
+ default:
93
+ throw new TypeError(`Unsupported case style: ${casing}`);
94
+ }
95
+ }
96
+ function replaceSeparatorsWithSpace(value) {
97
+ return toTitleCase(value.replace(/[-_]+/g, " ").replace(/\s+/g, " "));
98
+ }
99
+ function htmlToPlainText(value) {
100
+ if (value.trim().length === 0) {
101
+ return "";
102
+ }
103
+ return value.replace(/<(br|\/p|\/div|\/pre|\/li)\b[^>]*>/gi, " ").replace(/<[^>]*>/g, " ").replace(/[\n\t]+/g, " ").replace(/\s+/g, " ").trim();
104
+ }
105
+ function nonEmptyString(value) {
106
+ if (typeof value !== "string") {
107
+ return null;
108
+ }
109
+ const trimmed = value.trim();
110
+ return trimmed.length === 0 ? null : trimmed;
111
+ }
112
+
113
+ export { capitalize, convertCase, escapeHtml, escapeRegex as escapeRegExp, escapeRegex, htmlToPlainText, nonEmptyString, normalizeWhitespace, replaceSeparatorsWithSpace, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, toTitleCase };
114
+ //# sourceMappingURL=index.js.map
115
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/internal/validation.ts","../../src/string/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export function assertFiniteNumber(\r\n value: unknown,\r\n name: string,\r\n): asserts value is number {\r\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\r\n throw new TypeError(`${name} must be a finite number`);\r\n }\r\n}\r\n\r\nexport function escapeRegExp(value: string): string {\r\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n","import { escapeRegExp } from \"../internal/validation.js\";\r\n\r\nexport type TextCase =\r\n | \"title\"\r\n | \"titlecase\"\r\n | \"lower\"\r\n | \"lowercase\"\r\n | \"upper\"\r\n | \"uppercase\"\r\n | \"camel\"\r\n | \"camelcase\"\r\n | \"pascal\"\r\n | \"pascalcase\"\r\n | \"snake\"\r\n | \"snakecase\"\r\n | \"kebab\"\r\n | \"kebabcase\";\r\n\r\nconst HTML_ESCAPE_MAP: Record<string, string> = {\r\n \"&\": \"&amp;\",\r\n \"<\": \"&lt;\",\r\n \">\": \"&gt;\",\r\n '\"': \"&quot;\",\r\n \"'\": \"&#39;\",\r\n};\r\n\r\n/**\r\n * Splits mixed naming conventions into discrete words.\r\n * Handles spaces, hyphens, underscores, dots, and camel/PascalCase boundaries.\r\n */\r\nfunction splitWords(value: string): string[] {\r\n const trimmed = value.trim();\r\n if (trimmed.length === 0) {\r\n return [];\r\n }\r\n\r\n return trimmed\r\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\r\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\r\n .split(/[\\s._-]+/u)\r\n .filter((word) => word.length > 0);\r\n}\r\n\r\nfunction toLowerWords(value: string): string[] {\r\n return splitWords(value).map((word) => word.toLowerCase());\r\n}\r\n\r\nfunction capitalizeWord(word: string): string {\r\n const [first = \"\", ...rest] = [...word];\r\n return `${first.toUpperCase()}${rest.join(\"\").toLowerCase()}`;\r\n}\r\n\r\n/**\r\n * Converts a string to camelCase.\r\n *\r\n * @example\r\n * toCamelCase(\"hello-world\") // \"helloWorld\"\r\n * toCamelCase(\"XMLHttpRequest\") // \"xmlHttpRequest\"\r\n */\r\nexport function toCamelCase(value: string): string {\r\n const words = toLowerWords(value);\r\n if (words.length === 0) {\r\n return \"\";\r\n }\r\n\r\n const [first = \"\", ...rest] = words;\r\n return `${first}${rest.map(capitalizeWord).join(\"\")}`;\r\n}\r\n\r\n/**\r\n * Converts a string to PascalCase.\r\n *\r\n * @example\r\n * toPascalCase(\"hello_world\") // \"HelloWorld\"\r\n */\r\nexport function toPascalCase(value: string): string {\r\n return toLowerWords(value).map(capitalizeWord).join(\"\");\r\n}\r\n\r\n/**\r\n * Converts a string to snake_case.\r\n *\r\n * @example\r\n * toSnakeCase(\"Hello World\") // \"hello_world\"\r\n */\r\nexport function toSnakeCase(value: string): string {\r\n return toLowerWords(value).join(\"_\");\r\n}\r\n\r\n/**\r\n * Converts a string to kebab-case.\r\n *\r\n * @example\r\n * toKebabCase(\"HelloWorld\") // \"hello-world\"\r\n */\r\nexport function toKebabCase(value: string): string {\r\n return toLowerWords(value).join(\"-\");\r\n}\r\n\r\n/**\r\n * Trims the string and uppercases its first Unicode character.\r\n * The remaining characters are left unchanged.\r\n *\r\n * @example\r\n * capitalize(\" hello world\") // \"Hello world\"\r\n */\r\nexport function capitalize(value: string): string {\r\n const trimmed = value.trim();\r\n if (trimmed.length === 0) {\r\n return \"\";\r\n }\r\n\r\n const [first = \"\", ...rest] = [...trimmed];\r\n return `${first.toUpperCase()}${rest.join(\"\")}`;\r\n}\r\n\r\n/**\r\n * Trims leading and trailing whitespace and collapses internal\r\n * whitespace runs to a single space.\r\n *\r\n * @example\r\n * normalizeWhitespace(\" hello \\t\\n world \") // \"hello world\"\r\n */\r\nexport function normalizeWhitespace(value: string): string {\r\n return value.trim().replace(/\\s+/gu, \" \");\r\n}\r\n\r\n/**\r\n * Escapes `&`, `<`, `>`, `\"`, and `'` for safe interpolation into HTML text\r\n * or quoted attributes.\r\n *\r\n * This is not an HTML sanitizer. It does not parse markup, remove scripts,\r\n * or make untrusted HTML safe to render.\r\n *\r\n * @example\r\n * escapeHtml(`<img alt=\"O'Reilly & Co\">`)\r\n * // \"&lt;img alt=&quot;O&#39;Reilly &amp; Co&quot;&gt;\"\r\n */\r\nexport function escapeHtml(value: string): string {\r\n return value.replace(/[&<>\"']/g, (character) => HTML_ESCAPE_MAP[character] ?? character);\r\n}\r\n\r\n/**\r\n * Escapes special regular-expression characters in a string.\r\n *\r\n * @example\r\n * escapeRegex(\"file.name.txt\") // \"file\\\\.name\\\\.txt\"\r\n */\r\nexport function escapeRegex(value: string): string {\r\n return escapeRegExp(value);\r\n}\r\n\r\nexport { escapeRegex as escapeRegExp };\r\n\r\n/**\r\n * Converts a string to Title Case using word boundaries.\r\n *\r\n * @example\r\n * toTitleCase(\"hello world\") // \"Hello World\"\r\n * toTitleCase(\"used-truck\") // \"Used-Truck\"\r\n */\r\nexport function toTitleCase(value: string): string {\r\n const trimmed = value.trim();\r\n if (trimmed.length === 0) {\r\n return \"\";\r\n }\r\n\r\n return trimmed.toLowerCase().replace(/\\b\\w/g, (character) => character.toUpperCase());\r\n}\r\n\r\n/**\r\n * Converts a string to one of the supported case styles.\r\n * Unknown styles throw rather than silently falling back.\r\n *\r\n * @example\r\n * convertCase(\"hello world\", \"title\") // \"Hello World\"\r\n * convertCase(\"hello-world\", \"camel\") // \"helloWorld\"\r\n */\r\nexport function convertCase(value: string, casing: TextCase = \"title\"): string {\r\n switch (casing.toLowerCase() as TextCase) {\r\n case \"title\":\r\n case \"titlecase\":\r\n return toTitleCase(value);\r\n case \"lower\":\r\n case \"lowercase\":\r\n return value.trim().toLowerCase();\r\n case \"upper\":\r\n case \"uppercase\":\r\n return value.trim().toUpperCase();\r\n case \"camel\":\r\n case \"camelcase\":\r\n return toCamelCase(value);\r\n case \"pascal\":\r\n case \"pascalcase\":\r\n return toPascalCase(value);\r\n case \"snake\":\r\n case \"snakecase\":\r\n return toSnakeCase(value);\r\n case \"kebab\":\r\n case \"kebabcase\":\r\n return toKebabCase(value);\r\n default:\r\n throw new TypeError(`Unsupported case style: ${casing}`);\r\n }\r\n}\r\n\r\n/**\r\n * Replaces hyphens and underscores with spaces, then title-cases the result.\r\n *\r\n * @example\r\n * replaceSeparatorsWithSpace(\"used-truck\") // \"Used Truck\"\r\n * replaceSeparatorsWithSpace(\"hello_world\") // \"Hello World\"\r\n */\r\nexport function replaceSeparatorsWithSpace(value: string): string {\r\n return toTitleCase(value.replace(/[-_]+/g, \" \").replace(/\\s+/g, \" \"));\r\n}\r\n\r\n/**\r\n * Strips HTML tags and collapses whitespace into a single-line plain-text string.\r\n *\r\n * This is not an HTML sanitizer or a complete HTML parser. It does not decode\r\n * all entities or preserve document structure.\r\n *\r\n * @example\r\n * htmlToPlainText(\"<p>Hello<br>World</p>\") // \"Hello World\"\r\n */\r\nexport function htmlToPlainText(value: string): string {\r\n if (value.trim().length === 0) {\r\n return \"\";\r\n }\r\n\r\n return value\r\n .replace(/<(br|\\/p|\\/div|\\/pre|\\/li)\\b[^>]*>/gi, \" \")\r\n .replace(/<[^>]*>/g, \" \")\r\n .replace(/[\\n\\t]+/g, \" \")\r\n .replace(/\\s+/g, \" \")\r\n .trim();\r\n}\r\n\r\n/**\r\n * Returns a trimmed string, or `null` when the value is not a non-empty string.\r\n *\r\n * @example\r\n * nonEmptyString(\" Gold \") // \"Gold\"\r\n * nonEmptyString(\" \") // null\r\n */\r\nexport function nonEmptyString(value: unknown): string | null {\r\n if (typeof value !== \"string\") {\r\n return null;\r\n }\r\n\r\n const trimmed = value.trim();\r\n return trimmed.length === 0 ? null : trimmed;\r\n}\r\n"]}