@ppabari/strio 1.0.2 → 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/CHANGELOG.md +42 -0
- package/README.md +57 -3
- package/dist/bin/strio.js +53 -0
- package/dist/index.cjs +51 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -3
- package/dist/index.d.ts +51 -3
- package/dist/index.js +49 -1
- package/dist/index.js.map +1 -1
- package/dist/str.cjs +623 -0
- package/dist/str.cjs.map +1 -0
- package/dist/str.d.cts +579 -0
- package/dist/str.d.ts +579 -0
- package/dist/str.js +567 -0
- package/dist/str.js.map +1 -0
- package/dist/{zod-CINbFpp9.d.cts → zod-IWq12GIY.d.cts} +1 -1
- package/dist/{zod-CINbFpp9.d.ts → zod-IWq12GIY.d.ts} +1 -1
- package/dist/zod.d.cts +1 -1
- package/dist/zod.d.ts +1 -1
- package/package.json +31 -8
package/dist/str.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/str/internal.ts","../src/str/manipulation.ts","../src/str/case.ts","../src/str/validation.ts","../src/str/searching.ts","../src/core.ts","../src/charset-aliases.ts","../src/str/utilities.ts","../src/str/formatting.ts","../src/str/padding.ts","../src/str/security.ts","../src/str/ensuring.ts"],"names":["count","words"],"mappings":"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","file":"str.js","sourcesContent":["/**\n * str/internal.ts\n * Shared internal helpers for the string-utility toolkit.\n * NOT part of the public API (not re-exported from the barrel).\n */\n\n/** Throws a TypeError if the input is not a string. Used by every public helper. */\nexport function assertString(value: unknown, name = 'input'): asserts value is string {\n if (typeof value !== 'string') {\n throw new TypeError(`Expected ${name} to be a string, received ${typeof value}.`);\n }\n}\n\n/**\n * Split an arbitrary string into its constituent words, handling:\n * - camelCase / PascalCase boundaries (\"fooBar\" → [\"foo\", \"Bar\"])\n * - consecutive capitals / acronyms (\"APIResponse\" → [\"API\", \"Response\"])\n * - snake_case, kebab-case, spaces, dots (\"foo_bar-baz\" → [\"foo\", \"bar\", \"baz\"])\n * - digit boundaries (\"v2Point\" → [\"v\", \"2\", \"Point\"])\n *\n * Returns lowercase-preserving word chunks (case is preserved so callers can\n * decide how to recase). Empty chunks are dropped.\n */\nexport function extractWords(str: string): string[] {\n return (\n str\n // insert a space between a lowercase/number and an uppercase letter\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n // insert a space between an acronym run and a following word (APIResponse → API Response)\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n // insert a space between letters and digits\n .replace(/([a-zA-Z])([0-9])/g, '$1 $2')\n .replace(/([0-9])([a-zA-Z])/g, '$1 $2')\n // any run of non-alphanumeric characters becomes a separator\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n );\n}\n","/**\n * str/manipulation.ts\n * Core string manipulation helpers.\n */\n\nimport { assertString } from './internal.js';\n\n/**\n * Uppercase the first character of a string.\n *\n * @param str The input string.\n * @param lowerRest When `true`, the remaining characters are lowercased\n * (turning `'hELLO'` into `'Hello'`). Defaults to `false`.\n *\n * @example\n * capitalize('hello'); // → 'Hello'\n * capitalize('hELLO', true); // → 'Hello'\n */\nexport function capitalize(str: string, lowerRest = false): string {\n assertString(str);\n if (str.length === 0) return str;\n const rest = lowerRest ? str.slice(1).toLowerCase() : str.slice(1);\n return str.charAt(0).toUpperCase() + rest;\n}\n\n/**\n * Capitalize the first letter of every whitespace-separated word.\n *\n * @example\n * capitalizeWords('hello world'); // → 'Hello World'\n */\nexport function capitalizeWords(str: string): string {\n assertString(str);\n return str.replace(/(^|\\s)(\\S)/g, (_m, lead: string, ch: string) => lead + ch.toUpperCase());\n}\n\n/**\n * Reverse a string. Unicode-aware — surrogate pairs (e.g. emoji) stay intact.\n *\n * @example\n * reverse('abc'); // → 'cba'\n * reverse('a😀b'); // → 'b😀a'\n */\nexport function reverse(str: string): string {\n assertString(str);\n return [...str].reverse().join('');\n}\n\n/**\n * Truncate a string to at most `length` characters, appending `suffix`\n * (default `'…'`) when truncation occurs. The suffix counts toward `length`.\n *\n * @example\n * truncate('The quick brown fox', 9); // → 'The quic…'\n * truncate('The quick brown fox', 9, '...'); // → 'The qu...'\n * truncate('short', 20); // → 'short'\n */\nexport function truncate(str: string, length: number, suffix = '…'): string {\n assertString(str);\n if (str.length <= length) return str;\n if (length <= suffix.length) return suffix.slice(0, length);\n return str.slice(0, length - suffix.length) + suffix;\n}\n\n/**\n * Truncate a string to at most `count` words, appending `suffix`\n * (default `'…'`) when truncation occurs.\n *\n * @example\n * truncateWords('The quick brown fox', 2); // → 'The quick…'\n */\nexport function truncateWords(str: string, count: number, suffix = '…'): string {\n assertString(str);\n const parts = str.trim().split(/\\s+/).filter(Boolean);\n if (count <= 0) return suffix;\n if (parts.length <= count) return str;\n return parts.slice(0, count).join(' ') + suffix;\n}\n\n/**\n * Trim characters from both ends of a string. With no `chars` argument this\n * behaves like `String.prototype.trim` (all whitespace). When `chars` is\n * provided, every character in that set is stripped from both ends.\n *\n * @example\n * trim(' hi '); // → 'hi'\n * trim('__hi__', '_'); // → 'hi'\n * trim('xyabcyx', 'xy'); // → 'abc'\n */\nexport function trim(str: string, chars?: string): string {\n assertString(str);\n if (chars === undefined) return str.trim();\n if (chars.length === 0) return str;\n const set = new Set(chars);\n let start = 0;\n let end = str.length;\n while (start < end && set.has(str[start] as string)) start++;\n while (end > start && set.has(str[end - 1] as string)) end--;\n return str.slice(start, end);\n}\n\n/**\n * Insert `substring` into `str` at the given `index`. Negative indexes count\n * from the end; out-of-range indexes clamp to the nearest boundary.\n *\n * @example\n * insert('helloworld', 5, ' '); // → 'hello world'\n * insert('ac', 1, 'b'); // → 'abc'\n */\nexport function insert(str: string, index: number, substring: string): string {\n assertString(str);\n assertString(substring, 'substring');\n let i = index < 0 ? str.length + index : index;\n if (i < 0) i = 0;\n if (i > str.length) i = str.length;\n return str.slice(0, i) + substring + str.slice(i);\n}\n\nexport interface MaskOptions {\n /** Character used for masking. @default '*' */\n maskChar?: string;\n /** Number of leading characters left visible. @default 0 */\n visibleStart?: number;\n /** Number of trailing characters left visible. @default 0 */\n visibleEnd?: number;\n}\n\n/**\n * Mask the middle of a string, revealing only the first `visibleStart` and\n * last `visibleEnd` characters. Useful for redacting emails, cards, tokens.\n *\n * (For secret-grade masking with length hiding see `maskSecret` in the main\n * `@ppabari/strio` export.)\n *\n * @example\n * mask('4242424242424242', { visibleStart: 0, visibleEnd: 4 });\n * // → '************4242'\n * mask('john@example.com', { visibleStart: 2, visibleEnd: 0 });\n * // → 'jo**************'\n */\nexport function mask(str: string, options: MaskOptions = {}): string {\n assertString(str);\n const { maskChar = '*', visibleStart = 0, visibleEnd = 0 } = options;\n const chars = [...str];\n const len = chars.length;\n if (visibleStart + visibleEnd >= len) return str;\n const head = chars.slice(0, Math.max(0, visibleStart)).join('');\n const tail = visibleEnd > 0 ? chars.slice(len - visibleEnd).join('') : '';\n const maskedCount = len - Math.max(0, visibleStart) - Math.max(0, visibleEnd);\n return head + maskChar.repeat(maskedCount) + tail;\n}\n","/**\n * str/case.ts\n * Case-conversion helpers. All are built on the shared `extractWords` splitter,\n * so they handle camelCase, PascalCase, snake_case, kebab-case, spaces, and\n * mixed inputs consistently.\n */\n\nimport { assertString, extractWords } from './internal.js';\n\n/**\n * Convert a string to `camelCase`.\n *\n * @example\n * camelize('foo-bar'); // → 'fooBar'\n * camelize('Foo Bar Baz'); // → 'fooBarBaz'\n * camelize('foo_bar'); // → 'fooBar'\n */\nexport function camelize(str: string): string {\n assertString(str);\n const words = extractWords(str);\n if (words.length === 0) return '';\n return words\n .map((w, i) =>\n i === 0\n ? w.toLowerCase()\n : w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()\n )\n .join('');\n}\n\n/**\n * Convert a string to `PascalCase` (a.k.a. UpperCamelCase).\n *\n * @example\n * pascalize('foo-bar'); // → 'FooBar'\n * pascalize('foo bar'); // → 'FooBar'\n */\nexport function pascalize(str: string): string {\n assertString(str);\n return extractWords(str)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Convert a string to `kebab-case` (dash-separated, lowercase).\n *\n * @example\n * dasherize('fooBar'); // → 'foo-bar'\n * dasherize('Foo Bar'); // → 'foo-bar'\n * dasherize('foo_bar'); // → 'foo-bar'\n */\nexport function dasherize(str: string): string {\n assertString(str);\n return extractWords(str)\n .map((w) => w.toLowerCase())\n .join('-');\n}\n\n/**\n * Convert a string to `snake_case` (underscore-separated, lowercase).\n *\n * @example\n * underscore('fooBar'); // → 'foo_bar'\n * underscore('Foo-Bar'); // → 'foo_bar'\n */\nexport function underscore(str: string): string {\n assertString(str);\n return extractWords(str)\n .map((w) => w.toLowerCase())\n .join('_');\n}\n","/**\n * str/validation.ts\n * Boolean predicates for inspecting strings. These never throw — they return\n * `false` for non-string input (except `isString`, whose job is that check).\n */\n\n/**\n * Whether the value is a string primitive.\n *\n * @example\n * isString('a'); // → true\n * isString(42); // → false\n */\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/**\n * Whether the string has zero length. Non-strings are treated as empty.\n *\n * @example\n * isEmpty(''); // → true\n * isEmpty(' '); // → false\n */\nexport function isEmpty(value: unknown): boolean {\n return !isString(value) || value.length === 0;\n}\n\n/**\n * Whether the string is empty or contains only whitespace.\n *\n * @example\n * isBlank(' '); // → true\n * isBlank('\\n\\t'); // → true\n * isBlank('a'); // → false\n */\nexport function isBlank(value: unknown): boolean {\n return !isString(value) || value.trim().length === 0;\n}\n\n/**\n * Whether the string contains only ASCII letters (`A–Z`, `a–z`) and is\n * non-empty.\n *\n * @example\n * isAlpha('Hello'); // → true\n * isAlpha('Hi5'); // → false\n */\nexport function isAlpha(value: unknown): boolean {\n return isString(value) && /^[A-Za-z]+$/.test(value);\n}\n\n/**\n * Whether the string contains only ASCII digits (`0–9`) and is non-empty.\n * Note: this checks the *character class*, not numeric parseability — `'007'`\n * is numeric, `'-1'` and `'1.5'` are not.\n *\n * @example\n * isNumeric('12345'); // → true\n * isNumeric('1.5'); // → false\n */\nexport function isNumeric(value: unknown): boolean {\n return isString(value) && /^[0-9]+$/.test(value);\n}\n\n/**\n * Whether the string contains only ASCII letters and digits, and is non-empty.\n *\n * @example\n * isAlphaNumeric('abc123'); // → true\n * isAlphaNumeric('abc 12'); // → false\n */\nexport function isAlphaNumeric(value: unknown): boolean {\n return isString(value) && /^[A-Za-z0-9]+$/.test(value);\n}\n\n/**\n * Whether the string is fully uppercase. It must contain at least one cased\n * letter and be unchanged by `toUpperCase()`.\n *\n * @example\n * isUpperCase('HELLO'); // → true\n * isUpperCase('HELLO1'); // → true\n * isUpperCase('Hello'); // → false\n * isUpperCase('123'); // → false (no cased letters)\n */\nexport function isUpperCase(value: unknown): boolean {\n return isString(value) && /[A-Z]/.test(value) && value === value.toUpperCase();\n}\n\n/**\n * Whether the string is fully lowercase. It must contain at least one cased\n * letter and be unchanged by `toLowerCase()`.\n *\n * @example\n * isLowerCase('hello'); // → true\n * isLowerCase('Hello'); // → false\n */\nexport function isLowerCase(value: unknown): boolean {\n return isString(value) && /[a-z]/.test(value) && value === value.toLowerCase();\n}\n","/**\n * str/searching.ts\n * Substring searching, counting, and extraction helpers.\n */\n\nimport { assertString } from './internal.js';\n\nfunction normalize(s: string, caseSensitive: boolean): string {\n return caseSensitive ? s : s.toLowerCase();\n}\n\n/**\n * Whether `str` contains `substring`.\n *\n * @param caseSensitive Defaults to `true`.\n *\n * @example\n * contains('Hello World', 'World'); // → true\n * contains('Hello World', 'world'); // → false\n * contains('Hello World', 'world', false); // → true\n */\nexport function contains(str: string, substring: string, caseSensitive = true): boolean {\n assertString(str);\n assertString(substring, 'substring');\n return normalize(str, caseSensitive).includes(normalize(substring, caseSensitive));\n}\n\n/**\n * Whether `str` contains *every* substring in the list.\n *\n * @example\n * containsAll('the quick fox', ['the', 'fox']); // → true\n * containsAll('the quick fox', ['the', 'dog']); // → false\n */\nexport function containsAll(str: string, substrings: string[], caseSensitive = true): boolean {\n assertString(str);\n return substrings.every((s) => contains(str, s, caseSensitive));\n}\n\n/**\n * Whether `str` contains *at least one* substring in the list.\n *\n * @example\n * containsAny('the quick fox', ['cat', 'fox']); // → true\n * containsAny('the quick fox', ['cat', 'dog']); // → false\n */\nexport function containsAny(str: string, substrings: string[], caseSensitive = true): boolean {\n assertString(str);\n return substrings.some((s) => contains(str, s, caseSensitive));\n}\n\n/**\n * Count occurrences of `substring` within `str`.\n *\n * @param overlapping When `true`, counts overlapping matches\n * (`count('aaa', 'aa', true)` → 2). Defaults to `false`.\n *\n * @example\n * count('banana', 'a'); // → 3\n * count('aaaa', 'aa'); // → 2\n * count('aaaa', 'aa', true); // → 3\n */\nexport function count(str: string, substring: string, overlapping = false): number {\n assertString(str);\n assertString(substring, 'substring');\n if (substring.length === 0) return 0;\n let n = 0;\n let pos = 0;\n const step = overlapping ? 1 : substring.length;\n while ((pos = str.indexOf(substring, pos)) !== -1) {\n n++;\n pos += step;\n }\n return n;\n}\n\n/**\n * Extract the first substring found between `start` and `end` delimiters.\n * Returns an empty string if the pair is not found.\n *\n * @example\n * between('[a][b]', '[', ']'); // → 'a'\n * between('key=value;', '=', ';'); // → 'value'\n */\nexport function between(str: string, start: string, end: string): string {\n assertString(str);\n const startIdx = str.indexOf(start);\n if (startIdx === -1) return '';\n const from = startIdx + start.length;\n const endIdx = str.indexOf(end, from);\n if (endIdx === -1) return '';\n return str.slice(from, endIdx);\n}\n\n/**\n * Extract *all* non-overlapping substrings found between `start` and `end`\n * delimiters, in document order.\n *\n * @example\n * betweenAll('[a][b][c]', '[', ']'); // → ['a', 'b', 'c']\n */\nexport function betweenAll(str: string, start: string, end: string): string[] {\n assertString(str);\n const results: string[] = [];\n let pos = 0;\n while (true) {\n const startIdx = str.indexOf(start, pos);\n if (startIdx === -1) break;\n const from = startIdx + start.length;\n const endIdx = str.indexOf(end, from);\n if (endIdx === -1) break;\n results.push(str.slice(from, endIdx));\n pos = endIdx + end.length;\n }\n return results;\n}\n","/**\n * core.ts\n * Cryptographically secure, bias-free random byte generation.\n * Works in Node.js (>=18), browsers, Deno, and edge runtimes.\n */\n\n/**\n * Returns a single cryptographically secure random byte (0–255).\n * Uses the Web Crypto API universally — available natively in\n * Node >=18, all modern browsers, Deno, Cloudflare Workers, etc.\n */\nfunction getRandomByte(): number {\n const buf = new Uint8Array(1);\n crypto.getRandomValues(buf);\n return buf[0] as number;\n}\n\n/**\n * Returns a random character from `charset` with no modulo bias.\n *\n * Naive approach: index = randomByte % charset.length\n * Problem: If 256 is not evenly divisible by charset.length,\n * some characters appear slightly more often.\n *\n * Fix (rejection sampling):\n * Compute the largest multiple of charset.length that fits in 0–255.\n * Discard bytes >= that threshold and retry.\n * Expected retries: < 1 per character for any charset <= 128 chars.\n */\nexport function getRandomChar(charset: string): string {\n const len = charset.length;\n // Largest multiple of `len` that fits in a byte (0–255 range)\n const maxValid = 256 - (256 % len);\n\n let byte: number;\n do {\n byte = getRandomByte();\n } while (byte >= maxValid);\n\n return charset[byte % len] as string;\n}\n\n/**\n * Fills an array of `count` random characters from `charset`.\n * Batches the crypto call for efficiency.\n */\nexport function getRandomChars(charset: string, count: number): string[] {\n const len = charset.length;\n const maxValid = 256 - (256 % len);\n const result: string[] = [];\n\n // Over-allocate to avoid multiple round trips; 40% buffer is generous\n // for any realistic charset size.\n const bufSize = Math.ceil(count * 1.4) + 32;\n const buf = new Uint8Array(bufSize);\n\n while (result.length < count) {\n crypto.getRandomValues(buf);\n for (let i = 0; i < buf.length && result.length < count; i++) {\n const byte = buf[i] as number;\n if (byte < maxValid) {\n result.push(charset[byte % len] as string);\n }\n }\n // Extremely unlikely to need a second pass, but handles edge cases\n // like a 1-char charset (which is blocked by validation anyway)\n }\n\n return result;\n}\n","/**\n * charset-aliases.ts\n * Named character set aliases for common encoding schemes.\n * Pass any alias name as the `charset` option in generateRandomString.\n *\n * @example\n * import { generateRandomString, CHARSET_ALIASES } from '@ppabari/strio';\n * generateRandomString({ charset: CHARSET_ALIASES.base58, length: 22 });\n * // or via string shorthand:\n * generateRandomString({ charset: 'base58', length: 22 });\n */\n\nexport const CHARSET_ALIASES: Record<string, string> = {\n /**\n * Base16 — hex digits, lowercase.\n * Use for: hash representations, color codes, compact binary encoding.\n */\n base16: '0123456789abcdef',\n\n /** Base16 uppercase variant */\n base16upper: '0123456789ABCDEF',\n\n /**\n * Base32 — RFC 4648. Uppercase alpha + digits, no padding chars.\n * Use for: case-insensitive tokens, OTP secrets (Google Authenticator compatible).\n */\n base32: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',\n\n /**\n * Base32 hex — RFC 4648 §7. Sortable alternative to standard base32.\n */\n base32hex: '0123456789ABCDEFGHIJKLMNOPQRSTUV',\n\n /**\n * Base36 — digits + lowercase alpha.\n * Use for: short URLs, case-insensitive IDs, number system conversions.\n */\n base36: '0123456789abcdefghijklmnopqrstuvwxyz',\n\n /**\n * Base58 — Bitcoin alphabet. No 0/O/I/l to avoid visual ambiguity.\n * Use for: Bitcoin addresses, IPFS CIDs, human-readable tokens.\n */\n base58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',\n\n /**\n * Base62 — digits + lowercase + uppercase. Max density for alphanumeric.\n * Use for: URL shorteners, compact IDs, high-entropy tokens.\n */\n base62: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\n\n /**\n * Base64 URL-safe — RFC 4648 §5. No +/= padding; URL and filename safe.\n * Use for: JWT components, URL tokens, file names.\n */\n base64url: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_',\n\n /**\n * Alphanumeric — same as base62. Alias for clarity.\n */\n alphanumeric: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\n\n /**\n * Alpha — letters only, mixed case.\n */\n alpha: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\n\n /**\n * Numeric — digits only.\n */\n numeric: '0123456789',\n\n /**\n * Hex — alias for base16 lowercase.\n */\n hex: '0123456789abcdef',\n\n /**\n * Crockford Base32 — human-friendly, case-insensitive, excludes I/L/O/U.\n * Use for: serial numbers, redemption codes, user-facing IDs.\n */\n crockford32: '0123456789ABCDEFGHJKMNPQRSTVWXYZ',\n} as const;\n\nexport type CharsetAlias = keyof typeof CHARSET_ALIASES;\n\n/**\n * Resolve a charset value: if it matches a known alias, return the\n * corresponding character string; otherwise return the value as-is.\n *\n * This is called inside buildCharset so alias names work transparently\n * as the `charset` option.\n *\n * @example\n * resolveCharsetAlias('base58') // → '123456789ABCDEF...'\n * resolveCharsetAlias('abc') // → 'abc'\n */\nexport function resolveCharsetAlias(value: string): string {\n return CHARSET_ALIASES[value] ?? value;\n}\n","/**\n * str/utilities.ts\n * General-purpose string utilities: tokenizing, templating, similarity,\n * transliteration, and cryptographically-secure random strings.\n */\n\nimport { assertString } from './internal.js';\nimport { getRandomChars } from '../core.js';\nimport { resolveCharsetAlias, CHARSET_ALIASES } from '../charset-aliases.js';\n\n/**\n * Split a string into an array of words (runs of letters/digits), discarding\n * punctuation and whitespace. Unlike case conversion, this does NOT break\n * camelCase boundaries.\n *\n * @example\n * words('Hello, world! 42'); // → ['Hello', 'world', '42']\n */\nexport function words(str: string): string[] {\n assertString(str);\n return str.match(/[A-Za-z0-9]+/g) ?? [];\n}\n\n/**\n * Count the words in a string.\n *\n * @example\n * wordCount('the quick brown fox'); // → 4\n */\nexport function wordCount(str: string): number {\n return words(str).length;\n}\n\n/**\n * Join a list of values with a separator, skipping `null`, `undefined`, and\n * empty-string entries so you never get doubled or trailing separators.\n *\n * @param separator Defaults to `' '`.\n *\n * @example\n * join(['a', '', 'b', null, 'c']); // → 'a b c'\n * join(['2024', '01', '05'], '-'); // → '2024-01-05'\n */\nexport function join(values: Array<string | number | null | undefined>, separator = ' '): string {\n return values\n .filter((v) => v !== null && v !== undefined && v !== '')\n .join(separator);\n}\n\nexport interface TemplateOptions {\n /**\n * Value substituted for keys missing from `data`. When `undefined`\n * (default), the original `{{placeholder}}` is left untouched.\n */\n fallback?: string;\n}\n\n/**\n * Interpolate `{{key}}` placeholders in `str` with values from `data`.\n * Whitespace inside the braces is ignored (`{{ name }}` works). Values are\n * coerced to strings.\n *\n * @example\n * template('Hi {{name}}!', { name: 'Ada' }); // → 'Hi Ada!'\n * template('{{a}}/{{b}}', { a: 1, b: 2 }); // → '1/2'\n * template('Hi {{name}}', {}, { fallback: '?' }); // → 'Hi ?'\n */\nexport function template(\n str: string,\n data: Record<string, unknown>,\n options: TemplateOptions = {}\n): string {\n assertString(str);\n const { fallback } = options;\n return str.replace(/\\{\\{\\s*([\\w.$-]+)\\s*\\}\\}/g, (match, key: string) => {\n const value = data[key];\n if (value === undefined || value === null) {\n return fallback !== undefined ? fallback : match;\n }\n return String(value);\n });\n}\n\n/**\n * Generate a cryptographically-secure random string of the given `length`.\n * Uses the same bias-free Web-Crypto engine as the rest of `@ppabari/strio`.\n *\n * @param charset A named charset alias (e.g. `'base58'`, `'hex'`) or a raw\n * string of characters to draw from. Defaults to\n * `'alphanumeric'`.\n *\n * @example\n * random(16); // → 16 alphanumeric chars\n * random(8, 'hex'); // → 8 hex chars\n * random(4, 'ABC'); // → 4 chars from {A, B, C}\n */\nexport function random(length: number, charset: string = 'alphanumeric'): string {\n if (!Number.isInteger(length) || length < 0) {\n throw new RangeError(`length must be a non-negative integer, received ${length}.`);\n }\n const pool = resolveCharsetAlias(charset);\n if (pool.length < 2) {\n throw new RangeError('charset must contain at least 2 distinct characters.');\n }\n if (length === 0) return '';\n return getRandomChars(pool, length).join('');\n}\n\n/**\n * Secure random string of ASCII letters (mixed case).\n * @example randomAlpha(10); // → e.g. 'QwErTyUiOp'\n */\nexport function randomAlpha(length: number): string {\n return random(length, CHARSET_ALIASES.alpha!);\n}\n\n/**\n * Secure random string of digits.\n * @example randomNumeric(6); // → e.g. '048213'\n */\nexport function randomNumeric(length: number): string {\n return random(length, CHARSET_ALIASES.numeric!);\n}\n\n/**\n * Secure random string of ASCII letters and digits.\n * @example randomAlphanumeric(12);\n */\nexport function randomAlphanumeric(length: number): string {\n return random(length, CHARSET_ALIASES.alphanumeric!);\n}\n\n/**\n * Compute a normalized similarity ratio in `[0, 1]` between two strings,\n * based on Levenshtein edit distance (`1` = identical, `0` = nothing in\n * common). Two empty strings are considered identical.\n *\n * @example\n * similarity('kitten', 'sitting'); // → ~0.571\n * similarity('abc', 'abc'); // → 1\n */\nexport function similarity(a: string, b: string): number {\n assertString(a, 'a');\n assertString(b, 'b');\n if (a === b) return 1;\n const maxLen = Math.max(a.length, b.length);\n if (maxLen === 0) return 1;\n return 1 - levenshtein(a, b) / maxLen;\n}\n\n/** Iterative Levenshtein distance using a single rolling row. */\nfunction levenshtein(a: string, b: string): number {\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n let prev = Array.from({ length: b.length + 1 }, (_, i) => i);\n const curr = new Array<number>(b.length + 1);\n for (let i = 1; i <= a.length; i++) {\n curr[0] = i;\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n curr[j] = Math.min(curr[j - 1]! + 1, prev[j]! + 1, prev[j - 1]! + cost);\n }\n prev = curr.slice();\n }\n return prev[b.length]!;\n}\n\n// Common Latin-1 / Latin-Extended characters that don't decompose via NFKD.\nconst TRANSLITERATION_MAP: Record<string, string> = {\n 'ß': 'ss', // ß\n 'æ': 'ae', // æ\n 'Æ': 'AE', // Æ\n 'œ': 'oe', // œ\n 'Œ': 'OE', // Œ\n 'ø': 'o', // ø\n 'Ø': 'O', // Ø\n 'đ': 'd', // đ\n 'Đ': 'D', // Đ\n 'ð': 'd', // ð\n 'Ð': 'D', // Ð\n 'þ': 'th', // þ\n 'Þ': 'Th', // Þ\n 'ł': 'l', // ł\n 'Ł': 'L', // Ł\n};\n\n/**\n * Transliterate accented and special Latin characters to their closest ASCII\n * equivalents. Diacritics are stripped via Unicode NFKD normalization; a small\n * map handles ligatures and letters that don't decompose (ß, æ, ø, …).\n *\n * Non-Latin scripts are left unchanged.\n *\n * @example\n * transliterate('Héllo Wörld'); // → 'Hello World'\n * transliterate('Straße'); // → 'Strasse'\n * transliterate('naïve café'); // → 'naive cafe'\n */\nexport function transliterate(str: string): string {\n assertString(str);\n const mapped = [...str].map((ch) => TRANSLITERATION_MAP[ch] ?? ch).join('');\n // NFKD splits accented letters into base char + combining marks; strip the\n // marks in the Combining Diacritical Marks block (U+0300-U+036F).\n return mapped.normalize('NFKD').replace(/[̀-ͯ]/g, '');\n}\n","/**\n * str/formatting.ts\n * Human-facing formatting helpers.\n *\n * NOTE: `titleCase`, `pluralize`, and `ordinalize` implement **English** rules\n * only. Internationalization is out of scope.\n */\n\nimport { assertString, extractWords } from './internal.js';\nimport { transliterate } from './utilities.js';\n\n/**\n * Convert a machine identifier (snake_case, camelCase, kebab-case…) into a\n * human-readable sentence: words separated by spaces with the first letter\n * capitalized.\n *\n * @example\n * humanize('first_name'); // → 'First name'\n * humanize('userID'); // → 'User id'\n * humanize('created-at'); // → 'Created at'\n */\nexport function humanize(str: string): string {\n assertString(str);\n const words = extractWords(str).map((w) => w.toLowerCase());\n if (words.length === 0) return '';\n const [first, ...rest] = words;\n return [first!.charAt(0).toUpperCase() + first!.slice(1), ...rest].join(' ');\n}\n\n// Words that stay lowercase in title case unless they are first or last.\nconst TITLE_MINOR_WORDS = new Set([\n 'a', 'an', 'and', 'as', 'at', 'but', 'by', 'for', 'if', 'in', 'nor', 'of',\n 'on', 'or', 'per', 'the', 'to', 'via', 'vs',\n]);\n\n/**\n * Convert a string to Title Case using English conventions: every word is\n * capitalized except minor words (articles, short prepositions, conjunctions),\n * which stay lowercase unless they are the first or last word.\n *\n * @example\n * titleCase('the lord of the rings'); // → 'The Lord of the Rings'\n * titleCase('a tale of two cities'); // → 'A Tale of Two Cities'\n */\nexport function titleCase(str: string): string {\n assertString(str);\n const words = str.trim().split(/\\s+/).filter(Boolean);\n const last = words.length - 1;\n return words\n .map((word, i) => {\n const lower = word.toLowerCase();\n if (i !== 0 && i !== last && TITLE_MINOR_WORDS.has(lower)) return lower;\n return lower.charAt(0).toUpperCase() + lower.slice(1);\n })\n .join(' ');\n}\n\n/**\n * Convert a string into a URL-friendly slug: transliterated to ASCII,\n * lowercased, with runs of non-alphanumerics collapsed to `separator`.\n *\n * @param separator Word separator. Defaults to `'-'`.\n *\n * @example\n * slugify('Héllo, World!'); // → 'hello-world'\n * slugify('Foo Bar', '_'); // → 'foo_bar'\n */\nexport function slugify(str: string, separator = '-'): string {\n assertString(str);\n return transliterate(str)\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, separator)\n .replace(new RegExp(`^${escapeSep(separator)}+|${escapeSep(separator)}+$`, 'g'), '');\n}\n\nfunction escapeSep(sep: string): string {\n return sep.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Return the ordinal form of a number: `1` → `'1st'`, `2` → `'2nd'`,\n * `13` → `'13th'`, `22` → `'22nd'`. Accepts a number or a numeric string.\n *\n * @example\n * ordinalize(1); // → '1st'\n * ordinalize(11); // → '11th'\n * ordinalize(103); // → '103rd'\n */\nexport function ordinalize(n: number | string): string {\n const num = typeof n === 'number' ? n : parseInt(n, 10);\n if (!Number.isFinite(num)) throw new TypeError(`Expected a finite number, received ${n}.`);\n const abs = Math.abs(num) % 100;\n let suffix = 'th';\n if (abs < 11 || abs > 13) {\n switch (abs % 10) {\n case 1: suffix = 'st'; break;\n case 2: suffix = 'nd'; break;\n case 3: suffix = 'rd'; break;\n }\n }\n return `${num}${suffix}`;\n}\n\n// Irregular plurals and uncountable nouns.\nconst IRREGULAR_PLURALS: Record<string, string> = {\n child: 'children', person: 'people', man: 'men', woman: 'women',\n tooth: 'teeth', foot: 'feet', mouse: 'mice', goose: 'geese', ox: 'oxen',\n};\nconst UNCOUNTABLE = new Set([\n 'sheep', 'fish', 'series', 'species', 'deer', 'information', 'equipment',\n 'money', 'rice', 'news',\n]);\n\n/**\n * Pluralize an English word. If `count` is provided, the word is only\n * pluralized when `count !== 1`. Case of the first letter is preserved.\n *\n * @example\n * pluralize('cat'); // → 'cats'\n * pluralize('bus'); // → 'buses'\n * pluralize('city'); // → 'cities'\n * pluralize('child'); // → 'children'\n * pluralize('cat', 1); // → 'cat'\n * pluralize('cat', 3); // → 'cats'\n */\nexport function pluralize(word: string, count?: number): string {\n assertString(word, 'word');\n if (count === 1) return word;\n if (word.length === 0) return word;\n\n const lower = word.toLowerCase();\n const preserve = (result: string) =>\n word[0] === word[0]!.toUpperCase()\n ? result.charAt(0).toUpperCase() + result.slice(1)\n : result;\n\n if (UNCOUNTABLE.has(lower)) return word;\n if (IRREGULAR_PLURALS[lower]) return preserve(IRREGULAR_PLURALS[lower]!);\n\n if (/[^aeiou]y$/.test(lower)) return preserve(lower.slice(0, -1) + 'ies');\n if (/(s|ss|sh|ch|x|z)$/.test(lower)) return preserve(lower + 'es');\n if (/(fe?)$/.test(lower)) return preserve(lower.replace(/fe?$/, 'ves'));\n return preserve(lower + 's');\n}\n","/**\n * str/padding.ts\n * Padding and indentation helpers.\n */\n\nimport { assertString } from './internal.js';\n\n/**\n * Left-pad a string to `length` using `char` (default `' '`). Returns the\n * string unchanged if it is already at least `length`.\n *\n * @example\n * padLeft('7', 3, '0'); // → '007'\n * padLeft('hi', 5); // → ' hi'\n */\nexport function padLeft(str: string, length: number, char = ' '): string {\n assertString(str);\n if (char.length === 0) return str;\n return str.length >= length ? str : buildPad(char, length - str.length) + str;\n}\n\n/**\n * Right-pad a string to `length` using `char` (default `' '`).\n *\n * @example\n * padRight('7', 3, '0'); // → '700'\n */\nexport function padRight(str: string, length: number, char = ' '): string {\n assertString(str);\n if (char.length === 0) return str;\n return str.length >= length ? str : str + buildPad(char, length - str.length);\n}\n\n/**\n * Center a string within `length`, padding both sides with `char`. When the\n * padding can't be split evenly, the extra character goes on the right.\n *\n * @example\n * padCenter('hi', 6); // → ' hi '\n * padCenter('hi', 7, '*'); // → '**hi***'\n */\nexport function padCenter(str: string, length: number, char = ' '): string {\n assertString(str);\n if (char.length === 0 || str.length >= length) return str;\n const total = length - str.length;\n const left = Math.floor(total / 2);\n const right = total - left;\n return buildPad(char, left) + str + buildPad(char, right);\n}\n\n/** Build a pad of exactly `width` characters from a (possibly multi-char) unit. */\nfunction buildPad(char: string, width: number): string {\n if (width <= 0) return '';\n return char.repeat(Math.ceil(width / char.length)).slice(0, width);\n}\n\n/**\n * Indent every line of a string by `count` repetitions of `char`\n * (default: 2 spaces). Blank lines are left untouched by default.\n *\n * @param char The indentation unit. @default ' '\n * @param indentEmpty When `true`, blank lines are indented too. @default false\n *\n * @example\n * indent('a\\nb'); // → ' a\\n b'\n * indent('a\\nb', 1, '\\t'); // → '\\ta\\n\\tb'\n */\nexport function indent(str: string, count = 2, char = ' ', indentEmpty = false): string {\n assertString(str);\n const prefix = char.repeat(count);\n return str\n .split('\\n')\n .map((line) => (indentEmpty || line.length > 0 ? prefix + line : line))\n .join('\\n');\n}\n\n/**\n * Remove the common leading whitespace from every line — the inverse of\n * `indent`, useful for tidying template literals. Fully-blank lines are ignored\n * when computing the common indent, and leading/trailing blank lines are\n * trimmed.\n *\n * @example\n * dedent(' a\\n b'); // → 'a\\nb'\n * dedent('\\n foo\\n bar\\n'); // → 'foo\\n bar'\n */\nexport function dedent(str: string): string {\n assertString(str);\n const lines = str.replace(/^\\n/, '').replace(/\\n[ \\t]*$/, '').split('\\n');\n let min = Infinity;\n for (const line of lines) {\n if (line.trim().length === 0) continue;\n const leading = line.match(/^[ \\t]*/)![0].length;\n if (leading < min) min = leading;\n }\n if (!Number.isFinite(min) || min === 0) return lines.join('\\n');\n return lines.map((line) => line.slice(min)).join('\\n');\n}\n","/**\n * str/security.ts\n * Escaping, sanitizing, and safe-affix helpers.\n *\n * NOTE: `escapeHtml` / `stripTags` provide basic protection for text\n * interpolation. They are NOT a substitute for a full HTML sanitizer (e.g.\n * DOMPurify) when rendering untrusted rich markup.\n */\n\nimport { assertString } from './internal.js';\n\nconst HTML_ESCAPES: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n};\nconst HTML_UNESCAPES: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\",\n ''': \"'\",\n ''': \"'\",\n '/': '/',\n '/': '/',\n};\n\n/**\n * Escape the five characters that are significant in HTML (`& < > \" '`) so a\n * string can be safely interpolated into markup as text.\n *\n * @example\n * escapeHtml('<a href=\"x\">Tom & Jerry</a>');\n * // → '<a href="x">Tom & Jerry</a>'\n */\nexport function escapeHtml(str: string): string {\n assertString(str);\n return str.replace(/[&<>\"']/g, (ch) => HTML_ESCAPES[ch]!);\n}\n\n/**\n * Reverse `escapeHtml`, decoding the common named and numeric HTML entities.\n *\n * @example\n * unescapeHtml('<b>hi</b>'); // → '<b>hi</b>'\n */\nexport function unescapeHtml(str: string): string {\n assertString(str);\n return str.replace(/&(?:amp|lt|gt|quot|#39|#x27|apos|#x2F|#47);/g, (ent) => HTML_UNESCAPES[ent]!);\n}\n\n/**\n * Escape a string so it can be used literally inside a `RegExp` — every\n * regex-special character is backslash-escaped.\n *\n * @example\n * escapeRegExp('a.b*c'); // → 'a\\\\.b\\\\*c'\n * new RegExp(escapeRegExp('$5.00')).test('$5.00'); // → true\n */\nexport function escapeRegExp(str: string): string {\n assertString(str);\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Strip all HTML/XML tags from a string, leaving the text content.\n *\n * @example\n * stripTags('<p>Hello <b>world</b></p>'); // → 'Hello world'\n */\nexport function stripTags(str: string): string {\n assertString(str);\n return str.replace(/<[^>]*>/g, '');\n}\n\n/**\n * Collapse all runs of whitespace (spaces, tabs, newlines) into a single\n * space and trim the ends.\n *\n * @example\n * collapseWhitespace(' a\\n\\t b c '); // → 'a b c'\n */\nexport function collapseWhitespace(str: string): string {\n assertString(str);\n return str.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Remove `prefix` from the start of `str`, if present. Idempotent.\n *\n * @example\n * stripPrefix('usr_123', 'usr_'); // → '123'\n * stripPrefix('123', 'usr_'); // → '123'\n */\nexport function stripPrefix(str: string, prefix: string): string {\n assertString(str);\n assertString(prefix, 'prefix');\n return prefix.length > 0 && str.startsWith(prefix) ? str.slice(prefix.length) : str;\n}\n\n/**\n * Remove `suffix` from the end of `str`, if present. Idempotent.\n *\n * @example\n * stripSuffix('report.txt', '.txt'); // → 'report'\n * stripSuffix('report', '.txt'); // → 'report'\n */\nexport function stripSuffix(str: string, suffix: string): string {\n assertString(str);\n assertString(suffix, 'suffix');\n return suffix.length > 0 && str.endsWith(suffix) ? str.slice(0, -suffix.length) : str;\n}\n","/**\n * str/ensuring.ts\n * Idempotent affix helpers — guarantee a string starts/ends a certain way\n * without duplicating an affix that is already present.\n */\n\nimport { assertString } from './internal.js';\n\n/**\n * Ensure `str` starts with `prefix`, prepending it only if missing. Idempotent.\n *\n * @example\n * ensureLeft('example.com', 'https://'); // → 'https://example.com'\n * ensureLeft('https://example.com', 'https://'); // → 'https://example.com'\n */\nexport function ensureLeft(str: string, prefix: string): string {\n assertString(str);\n assertString(prefix, 'prefix');\n return str.startsWith(prefix) ? str : prefix + str;\n}\n\n/**\n * Ensure `str` ends with `suffix`, appending it only if missing. Idempotent.\n *\n * @example\n * ensureRight('path', '/'); // → 'path/'\n * ensureRight('path/', '/'); // → 'path/'\n */\nexport function ensureRight(str: string, suffix: string): string {\n assertString(str);\n assertString(suffix, 'suffix');\n return str.endsWith(suffix) ? str : str + suffix;\n}\n"]}
|
|
@@ -208,4 +208,4 @@ interface ZodLike {
|
|
|
208
208
|
*/
|
|
209
209
|
declare function randomStringSchema(options?: RandomStringSchemaOptions, zod?: ZodLike): ZodStringLike;
|
|
210
210
|
|
|
211
|
-
export { type EntropyResult as E, type RandomStringOptions as R, type StartWith as S, type ValidateOptions as V, type
|
|
211
|
+
export { type EntropyResult as E, type RandomStringOptions as R, type StartWith as S, type ValidateOptions as V, type ValidationResult as a, type RandomStringResult as b, type RandomStringSchemaOptions as c, randomStringSchema as r };
|
|
@@ -208,4 +208,4 @@ interface ZodLike {
|
|
|
208
208
|
*/
|
|
209
209
|
declare function randomStringSchema(options?: RandomStringSchemaOptions, zod?: ZodLike): ZodStringLike;
|
|
210
210
|
|
|
211
|
-
export { type EntropyResult as E, type RandomStringOptions as R, type StartWith as S, type ValidateOptions as V, type
|
|
211
|
+
export { type EntropyResult as E, type RandomStringOptions as R, type StartWith as S, type ValidateOptions as V, type ValidationResult as a, type RandomStringResult as b, type RandomStringSchemaOptions as c, randomStringSchema as r };
|
package/dist/zod.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { c as RandomStringSchemaOptions, r as randomStringSchema } from './zod-IWq12GIY.cjs';
|
package/dist/zod.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { c as RandomStringSchemaOptions, r as randomStringSchema } from './zod-IWq12GIY.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ppabari/strio",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Cryptographically secure string generation for Node.js and browsers. Tokens, IDs, passphrases, patterns, expiring tokens — bias-free, zero dependencies, fully typed.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"random",
|
|
@@ -25,7 +25,18 @@
|
|
|
25
25
|
"base58",
|
|
26
26
|
"base62",
|
|
27
27
|
"hex-key",
|
|
28
|
-
"cookie-secret"
|
|
28
|
+
"cookie-secret",
|
|
29
|
+
"string",
|
|
30
|
+
"string-utils",
|
|
31
|
+
"slugify",
|
|
32
|
+
"camelcase",
|
|
33
|
+
"case-conversion",
|
|
34
|
+
"truncate",
|
|
35
|
+
"capitalize",
|
|
36
|
+
"pluralize",
|
|
37
|
+
"escape-html",
|
|
38
|
+
"levenshtein",
|
|
39
|
+
"transliterate"
|
|
29
40
|
],
|
|
30
41
|
"homepage": "https://github.com/parthpabari/strio#readme",
|
|
31
42
|
"bugs": {
|
|
@@ -51,6 +62,11 @@
|
|
|
51
62
|
"types": "./dist/zod.d.ts",
|
|
52
63
|
"import": "./dist/zod.js",
|
|
53
64
|
"require": "./dist/zod.cjs"
|
|
65
|
+
},
|
|
66
|
+
"./str": {
|
|
67
|
+
"types": "./dist/str.d.ts",
|
|
68
|
+
"import": "./dist/str.js",
|
|
69
|
+
"require": "./dist/str.cjs"
|
|
54
70
|
}
|
|
55
71
|
},
|
|
56
72
|
"main": "./dist/index.cjs",
|
|
@@ -73,6 +89,9 @@
|
|
|
73
89
|
"test:coverage": "vitest run --coverage",
|
|
74
90
|
"typecheck": "tsc --noEmit",
|
|
75
91
|
"lint": "tsc --noEmit",
|
|
92
|
+
"docs:dev": "vitepress dev docs",
|
|
93
|
+
"docs:build": "vitepress build docs",
|
|
94
|
+
"docs:preview": "vitepress preview docs",
|
|
76
95
|
"prepublishOnly": "npm run typecheck && npm run build && npm run test"
|
|
77
96
|
},
|
|
78
97
|
"peerDependencies": {
|
|
@@ -84,12 +103,16 @@
|
|
|
84
103
|
}
|
|
85
104
|
},
|
|
86
105
|
"devDependencies": {
|
|
87
|
-
"@types/node": "^
|
|
88
|
-
"@vitest/coverage-v8": "^1.
|
|
89
|
-
"tsup": "^8.
|
|
90
|
-
"typescript": "^
|
|
91
|
-
"
|
|
92
|
-
"
|
|
106
|
+
"@types/node": "^26.1.0",
|
|
107
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
108
|
+
"tsup": "^8.5.1",
|
|
109
|
+
"typescript": "^6.0.3",
|
|
110
|
+
"vitepress": "2.0.0-alpha.18",
|
|
111
|
+
"vitest": "^4.1.10",
|
|
112
|
+
"zod": "^4.4.3"
|
|
113
|
+
},
|
|
114
|
+
"overrides": {
|
|
115
|
+
"esbuild": "0.27.2"
|
|
93
116
|
},
|
|
94
117
|
"engines": {
|
|
95
118
|
"node": ">=18.0.0"
|