UNPKG

replace-quotes

Version:
63 lines (62 loc) 2.34 kB
// src/index.ts import { z } from "zod"; import { inspect } from "node-inspect-extracted"; var matchSchema = z.union([ z.string(), z.tuple([z.string(), z.string()]), z.tuple([z.string(), z.string(), z.boolean()]) ]); var replaceSchema = z.union([z.string(), z.tuple([z.string(), z.string()])]); var matchString = "string | [string, string] | [string, string, boolean]"; var replaceString = "string | [string, string]"; var double = String.fromCharCode(34); var single = String.fromCharCode(39); var backtick = String.fromCharCode(96); function replaceQuotes(...quotes) { if (quotes.length < 2) throw new Error("At least two arguments are required"); quotes.forEach((quote, index) => { const isLast = index + 1 === quotes.length; const result = (isLast ? replaceSchema : matchSchema).safeParse(quote); if (!result.success) { throw new Error( "Invalid argument at index " + index + "\nExpected: " + (isLast ? replaceString : matchString) + "\nGot: " + inspect(quote) ); } }); const sourceQuotesPairs = quotes.map((f) => Array.isArray(f) ? f : [f, f]); const [targetStartQuote, targetEndQuote] = sourceQuotesPairs.pop(); const getLiteralsRegex = new RegExp( sourceQuotesPairs.map( // to match string literal ([start, end]) => "(" + start + "(?:[^" + end + "\\\\]|\\\\.)*" + end + ")" ).concat( // to match regex literal "/(?:[^/\\\\]|\\\\.)*/", "\\[Function:? .*?\\]", "\\[class .*?\\]", "Symbol\\(.*?\\)" ).join("|"), "g" ); const getUnescapedTargetEndQuotesRegex = new RegExp( "(?<!\\\\)(?:\\\\\\\\)*" + targetEndQuote, "g" ); return (text) => text.replaceAll(getLiteralsRegex, (...match) => { const groups = match.slice(1, sourceQuotesPairs.length + 1); if (!groups.some(Boolean)) return match[0]; const [matchedSourceStartQuote, matchedSourceEndQuote, onlyForContext] = sourceQuotesPairs[groups.findIndex(Boolean)]; if (onlyForContext) return match[0]; let newString = match[0].slice(1, -1).replaceAll( new RegExp("\\\\" + matchedSourceEndQuote, "g"), matchedSourceEndQuote ).replaceAll(getUnescapedTargetEndQuotesRegex, (m) => "\\" + m); return targetStartQuote + newString + targetEndQuote; }); } export { backtick, replaceQuotes as default, double, single };