UNPKG

strkits

Version:
345 lines (344 loc) 12.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StrKits = exports.getLineBreakChar = exports.replaceRange = exports.transformToTitleCase = exports.transformToSnakeCase = exports.transformToKebabCase = exports.transformToPascalCase = exports.transformToCamelCase = exports.transformToSpecialCase = exports.strip = exports.removedMultiplesCharacters = exports.isUpperCase = exports.isSpecialCharacter = void 0; const py_range_ts_1 = require("py-range-ts"); const EMPTY_STRING = ''; const SPACE_STRING = ' '; const specialCharacterRanges = Object.freeze([ [33, 47], [58, 64], [92, 96], // from \ to ` ]); const SEPARATORS = Object.freeze(['-'.charCodeAt(0), ' '.charCodeAt(0), '_'.charCodeAt(0)]); function mkResult(callbackFn) { return callbackFn(); } function isSeparator(c) { return SEPARATORS.includes(c.charCodeAt(0)); } /** * Check if the subject is a special character ? */ function isSpaceOrSpecialCharacter(subject) { const charCode = subject.charCodeAt(0); // if is space if (charCode === 32) return true; for (const [start, end] of specialCharacterRanges) { if (charCode >= start && charCode <= end) return true; } return false; } function transformToPascalCamelCase(subject, firstIsUpperCase) { if (subject.length === 0) return EMPTY_STRING; if (subject.length === 1) { if (isSeparator(subject)) return EMPTY_STRING; if (firstIsUpperCase) return subject.toUpperCase(); return subject.toLowerCase(); } let beforeIsSeparator = true; let beforeIsUpperCase = false; const lengthMinus1 = subject.length - 1; const processedStrings = []; (0, py_range_ts_1.pyRange)(lengthMinus1).forEach((i) => { const currentLetter = subject[i]; // * Case: Special character if (isSpaceOrSpecialCharacter(currentLetter)) { beforeIsUpperCase = false; if (isSeparator(currentLetter)) { beforeIsSeparator = true; return; } return processedStrings.push(currentLetter); } // * Case Uppercase if (isUpperCase(currentLetter)) { if (beforeIsUpperCase && isUpperCase(subject[i + 1])) { beforeIsSeparator = false; beforeIsUpperCase = true; return processedStrings.push(currentLetter.toLowerCase()); } beforeIsSeparator = false; beforeIsUpperCase = true; return processedStrings.push(currentLetter); } beforeIsUpperCase = false; if (beforeIsSeparator) { beforeIsSeparator = false; return processedStrings.push(currentLetter.toUpperCase()); } return processedStrings.push(currentLetter); }); processedStrings.push(mkResult(() => { const currentLetter = subject[lengthMinus1]; // * Case: Special character if (isSpaceOrSpecialCharacter(currentLetter)) { if (isSeparator(currentLetter)) return EMPTY_STRING; return currentLetter; } // * Case: Upper case if (isUpperCase(currentLetter)) { if (beforeIsUpperCase) return currentLetter.toLowerCase(); return currentLetter; } // * Case: Lower case if (beforeIsSeparator) return currentLetter.toUpperCase(); return currentLetter; })); if (firstIsUpperCase) { processedStrings[0] = processedStrings[0].toUpperCase(); } else { processedStrings[0] = processedStrings[0].toLowerCase(); } return processedStrings.join(EMPTY_STRING); } function isSpecialCharacter(subject) { if (subject.length !== 1) { throw new Error(`[isASpecialCharacter] Accepts only 1 character. But subject.length=${subject.length}`); } const charCode = subject.charCodeAt(0); for (const [start, end] of specialCharacterRanges) { if (charCode >= start && charCode <= end) return true; } return false; } exports.isSpecialCharacter = isSpecialCharacter; function isUpperCase(subject) { return subject === subject.toUpperCase(); } exports.isUpperCase = isUpperCase; function removedMultiplesCharacters(subject, characters) { if (subject.length === 0) return EMPTY_STRING; const processedStrings = []; let tmp = undefined; for (let i = 0; i < subject.length; i++) { const currentLetter = subject[i]; if (tmp === currentLetter) { continue; } processedStrings.push(currentLetter); if (characters.includes(currentLetter)) { tmp = currentLetter; continue; } tmp = undefined; } return strip(processedStrings.join(EMPTY_STRING), characters); } exports.removedMultiplesCharacters = removedMultiplesCharacters; /** * Works like strip() in python * @param subject The string that will be trimmed * @param characters A string or list of strings specifying the set of * characters to be removed from the left and right part of the string. * @returns The string with both leading and trailing characters stripped. */ function strip(subject, characters) { if (subject.length === 0) return EMPTY_STRING; let start = -1; let end = -1; for (let i = 0; i < subject.length; i++) { if (!characters.includes(subject.charAt(i))) { start = i; break; } } if (start === -1 || start === subject.length - 1) return EMPTY_STRING; for (let i = subject.length - 1; i >= 0; i--) { if (!characters.includes(subject[i])) { end = i + 1; break; } } if (end <= start) return EMPTY_STRING; if (start === 0 && end === subject.length) return subject; return subject.slice(start, end); } exports.strip = strip; function transformToSpecialCase(subject, separator) { if (separator.length !== 1 || !isSeparator(separator)) { throw new Error('[transformToSpecialCase] Invalid separator'); } if (subject.length === 0) return EMPTY_STRING; if (subject.length === 1) { if (isSeparator(subject)) return EMPTY_STRING; return subject.toLowerCase(); } let beforeIsSpecialCharacter = false; let beforeIsUpperCase = false; let beforeIsSeparator = true; const lengthMinus1 = subject.length - 1; const processedStrings = []; (0, py_range_ts_1.pyRange)(lengthMinus1).forEach((i) => { const currentLetter = subject[i]; // * Case: Special character if (isSpaceOrSpecialCharacter(currentLetter)) { beforeIsSpecialCharacter = true; beforeIsUpperCase = false; if (isSeparator(currentLetter)) { if (beforeIsSeparator) return; beforeIsSeparator = true; return processedStrings.push(separator); } beforeIsSeparator = false; return processedStrings.push(currentLetter); } beforeIsSeparator = false; // * Case: Lower case if (!isUpperCase(currentLetter)) { beforeIsSpecialCharacter = false; beforeIsUpperCase = false; return processedStrings.push(currentLetter); } // * Case: Upper case const letterLower = currentLetter.toLowerCase(); if (beforeIsSpecialCharacter || (beforeIsUpperCase && isUpperCase(subject[i + 1]))) { beforeIsSpecialCharacter = false; beforeIsUpperCase = true; return processedStrings.push(letterLower); } beforeIsSpecialCharacter = false; beforeIsUpperCase = true; return processedStrings.push(separator + letterLower); }); processedStrings.push(mkResult(() => { const currentLetter = subject[lengthMinus1]; // * Case: Special character if (isSpaceOrSpecialCharacter(currentLetter)) { if (isSeparator(currentLetter)) return separator; return currentLetter; } // * Case: Lower case if (!isUpperCase(currentLetter)) return currentLetter; // * Case: Upper case const letterLower = currentLetter.toLowerCase(); if (beforeIsSpecialCharacter || beforeIsUpperCase) return letterLower; return separator + letterLower; })); return strip(processedStrings.join(EMPTY_STRING), separator); } exports.transformToSpecialCase = transformToSpecialCase; function transformToCamelCase(subject) { return transformToPascalCamelCase(subject, false); } exports.transformToCamelCase = transformToCamelCase; function transformToPascalCase(subject) { return transformToPascalCamelCase(subject, true); } exports.transformToPascalCase = transformToPascalCase; function transformToKebabCase(subject) { return transformToSpecialCase(subject, '-'); } exports.transformToKebabCase = transformToKebabCase; function transformToSnakeCase(subject) { return transformToSpecialCase(subject, '_'); } exports.transformToSnakeCase = transformToSnakeCase; function transformToTitleCase(subject, separator = ' ') { if (!isSeparator(separator) || separator.length !== 1) { throw new Error(`[transformToTitleCase] separator must be one of ${SEPARATORS.map((v) => String.fromCharCode(v)).join('|')} `); } let beforeIsSeparator = true; const processedStrings = transformToSpecialCase(subject, separator).split(EMPTY_STRING); for (let i = 0; i < processedStrings.length; i++) { if (processedStrings[i] === separator) { beforeIsSeparator = true; continue; } if (beforeIsSeparator) { processedStrings[i] = processedStrings[i].toUpperCase(); } beforeIsSeparator = false; } return processedStrings.join(EMPTY_STRING); } exports.transformToTitleCase = transformToTitleCase; function isValidReplaceRangeArgs(args, max) { if (args[0].start < 0) return false; if (args[args.length - 1].end > max) return false; let previous = 0; for (const { start, end } of args) { if (start > end || previous > start) return false; previous = end; } return true; } function replaceRange(subject, args) { if (args.length === 0) return subject; const argsCopy = [...args]; argsCopy.sort(({ start: a }, { start: b }) => { if (a > b) return 1; if (a < b) return -1; return 0; }); if (!isValidReplaceRangeArgs(argsCopy, subject.length)) { throw new Error('[replaceRange] Invalid args'); } const results = []; let previous = 0; for (const { start, end, value: newValue } of argsCopy) { results.push(subject.slice(previous, start)); results.push(newValue); previous = end; } if (previous < subject.length) { results.push(subject.slice(previous, subject.length)); } return results.join(''); } exports.replaceRange = replaceRange; function getLineBreakChar(subject) { const indexOfLF = subject.indexOf('\n', 1); if (indexOfLF === -1) { if (subject.indexOf('\r') !== -1) return '\r'; return '\n'; } if (subject[indexOfLF - 1] === '\r') return '\r\n'; return '\n'; } exports.getLineBreakChar = getLineBreakChar; exports.StrKits = Object.freeze({ isUpperCase, isSpecialCharacter, strip, removedMultiplesCharacters, replaceRange, getLineBreakChar, transform: Object.freeze({ toCamelCase: transformToCamelCase, toPascalCase: transformToPascalCase, toKebabCase: transformToKebabCase, toSnakeCase: transformToSnakeCase, toTitleCase: transformToTitleCase, toSpecialCase: transformToSpecialCase, }), }); exports.default = exports.StrKits;