{"version":3,"sources":["../../src/utils/string-formatter.ts"],"sourcesContent":["/**\r\n * String formatting utilities for Internet Object serialization.\r\n * Consolidates quoting, escaping, and format detection logic.\r\n * Ensures DRY principle and consistent string handling across serialization modules.\r\n */\r\n\r\nimport TypedefRegistry from '../schema/typedef-registry';\r\nimport MemberDef from '../schema/types/memberdef';\r\nimport { STRING_ENCLOSERS } from '../facade/serialization-constants';\r\n\r\n/**\r\n * String format types supported by Internet Object\r\n */\r\nexport type StringFormat = 'auto' | 'open' | 'regular' | 'raw' | 'multiline';\r\n\r\n/**\r\n * Quotes a string value using the appropriate format and encloser.\r\n *\r\n * @param str The string to quote\r\n * @param format The string format to use (default: 'regular')\r\n * @param encloser The quote character to use (default: '\"')\r\n * @returns Properly quoted and escaped string\r\n *\r\n * @example\r\n * ```typescript\r\n * quoteString('hello world')\r\n * // → \"hello world\"\r\n *\r\n * quoteString('it\\'s great', 'regular', '\"')\r\n * // → \"it's great\"\r\n *\r\n * quoteString('raw\\\\ntext', 'raw', \"'\")\r\n * // → 'raw\\\\ntext'\r\n * ```\r\n */\r\nexport function quoteString(\r\n  str: string,\r\n  format: StringFormat = 'regular',\r\n  encloser: string = STRING_ENCLOSERS.REGULAR\r\n): string {\r\n  // Use string typedef for proper formatting if available\r\n  const stringDef = TypedefRegistry.get('string');\r\n\r\n  if (stringDef && 'stringify' in stringDef && typeof stringDef.stringify === 'function') {\r\n    const pseudoMember: MemberDef = {\r\n      type: 'string',\r\n      path: '',\r\n      optional: false,\r\n      null: false,\r\n      format: format,\r\n      escapeLines: false,\r\n      encloser: encloser\r\n    } as any;\r\n\r\n    try {\r\n      return stringDef.stringify(str, pseudoMember) ?? fallbackQuoteString(str, encloser);\r\n    } catch (error) {\r\n      // Fallback on typedef failure\r\n      return fallbackQuoteString(str, encloser);\r\n    }\r\n  }\r\n\r\n  // Fallback if typedef not available\r\n  return fallbackQuoteString(str, encloser);\r\n}\r\n\r\n/**\r\n * Fallback string quoting when typedef is unavailable.\r\n * Handles basic escaping for quotes and control characters.\r\n *\r\n * @param str String to quote\r\n * @param encloser Quote character\r\n * @returns Quoted string\r\n */\r\nfunction fallbackQuoteString(str: string, encloser: string): string {\r\n  // Escape the encloser character and backslashes\r\n  const escaped = str\r\n    .replace(/\\\\/g, '\\\\\\\\')\r\n    .replace(new RegExp(encloser, 'g'), '\\\\' + encloser);\r\n\r\n  return encloser + escaped + encloser;\r\n}\r\n\r\n/**\r\n * Determines if a string needs quoting to avoid parser ambiguity.\r\n * Unquoted strings must not be confused with numbers, booleans, nulls, or dates.\r\n *\r\n * @param str The string to check\r\n * @returns True if the string requires quotes\r\n *\r\n * @example\r\n * ```typescript\r\n * needsQuoting('hello')      // → false (safe identifier)\r\n * needsQuoting('123')        // → true (looks like number)\r\n * needsQuoting('0001')       // → true (looks like number, has leading zeros)\r\n * needsQuoting('true')       // → true (looks like boolean)\r\n * needsQuoting('hello world') // → true (contains space)\r\n * needsQuoting('')           // → true (empty string)\r\n * ```\r\n */\r\nexport function needsQuoting(str: string): boolean {\r\n  // Empty strings always need quotes\r\n  if (str.length === 0) return true;\r\n\r\n  // Check for whitespace\r\n  if (/\\s/.test(str)) return true;\r\n\r\n  // Check if it looks like a number (starts with digit, or -/+/. followed by digit)\r\n  // This catches: \"123\", \"0001\", \"-5\", \".5\", \"3.14\", etc.\r\n  if (looksLikeNumber(str)) return true;\r\n\r\n  // Check if it looks like a boolean\r\n  if (str === 'T' || str === 'F' || str === 'true' || str === 'false') return true;\r\n\r\n  // Check if it looks like null\r\n  if (str === 'N' || str === 'null' || str === 'undefined') return true;\r\n\r\n  // Check if it starts with date/time markers\r\n  if (/^(d|t|dt)\"/.test(str)) return true;\r\n\r\n  // Check for special characters that require quoting\r\n  if (/[,\\[\\]{}:~@$]/.test(str)) return true;\r\n\r\n  // Safe to use unquoted\r\n  return false;\r\n}\r\n\r\n/**\r\n * Check if a string looks like a number when parsed.\r\n * Any string starting with a digit (or -/+/. followed by digit) looks like a number.\r\n */\r\nfunction looksLikeNumber(str: string): boolean {\r\n  if (str.length === 0) return false;\r\n\r\n  const first = str[0];\r\n  if (first === '-' || first === '+') {\r\n    if (str.length === 1) return false;\r\n    const second = str[1];\r\n    return (second >= '0' && second <= '9') || second === '.';\r\n  }\r\n  if (first === '.') {\r\n    if (str.length === 1) return false;\r\n    const second = str[1];\r\n    return second >= '0' && second <= '9';\r\n  }\r\n  return first >= '0' && first <= '9';\r\n}\r\n\r\n/**\r\n * Escapes special characters in a string value.\r\n *\r\n * @param str String to escape\r\n * @param encloser Quote character being used\r\n * @returns Escaped string (without quotes)\r\n */\r\nexport function escapeString(str: string, encloser: string = '\"'): string {\r\n  return str\r\n    .replace(/\\\\/g, '\\\\\\\\')         // Backslash\r\n    .replace(/\\n/g, '\\\\n')          // Newline\r\n    .replace(/\\r/g, '\\\\r')          // Carriage return\r\n    .replace(/\\t/g, '\\\\t')          // Tab\r\n    .replace(new RegExp(encloser, 'g'), '\\\\' + encloser); // Encloser\r\n}\r\n\r\n/**\r\n * Unescapes a quoted string value.\r\n *\r\n * @param str Escaped string (without quotes)\r\n * @returns Unescaped string\r\n */\r\nexport function unescapeString(str: string): string {\r\n  return str\r\n    .replace(/\\\\n/g, '\\n')\r\n    .replace(/\\\\r/g, '\\r')\r\n    .replace(/\\\\t/g, '\\t')\r\n    .replace(/\\\\\"/g, '\"')\r\n    .replace(/\\\\'/g, \"'\")\r\n    .replace(/\\\\\\\\/g, '\\\\');\r\n}\r\n\r\n/**\r\n * Quotes a string for header definition values.\r\n * Always uses regular format with quote encloser for fidelity.\r\n *\r\n * @param str String to quote for header\r\n * @returns Quoted string suitable for header definitions\r\n */\r\nexport function quoteHeaderString(str: string): string {\r\n  return quoteString(str, 'regular', STRING_ENCLOSERS.REGULAR);\r\n}\r\n\r\n/**\r\n * Quotes a string for wildcard extra property values.\r\n * Uses regular format to avoid parser ambiguity with identifiers.\r\n *\r\n * @param str String to quote\r\n * @returns Quoted string for extra properties\r\n */\r\nexport function quoteExtraPropertyString(str: string): string {\r\n  return quoteString(str, 'auto', STRING_ENCLOSERS.REGULAR);\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,8BAA4B;AAE5B,qCAAiC;AA2B1B,SAAS,YACd,KACA,SAAuB,WACvB,WAAmB,gDAAiB,SAC5B;AAER,QAAM,YAAY,wBAAAA,QAAgB,IAAI,QAAQ;AAE9C,MAAI,aAAa,eAAe,aAAa,OAAO,UAAU,cAAc,YAAY;AACtF,UAAM,eAA0B;AAAA,MAC9B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,MACN;AAAA,MACA,aAAa;AAAA,MACb;AAAA,IACF;AAEA,QAAI;AACF,aAAO,UAAU,UAAU,KAAK,YAAY,KAAK,oBAAoB,KAAK,QAAQ;AAAA,IACpF,SAAS,OAAO;AAEd,aAAO,oBAAoB,KAAK,QAAQ;AAAA,IAC1C;AAAA,EACF;AAGA,SAAO,oBAAoB,KAAK,QAAQ;AAC1C;AAUA,SAAS,oBAAoB,KAAa,UAA0B;AAElE,QAAM,UAAU,IACb,QAAQ,OAAO,MAAM,EACrB,QAAQ,IAAI,OAAO,UAAU,GAAG,GAAG,OAAO,QAAQ;AAErD,SAAO,WAAW,UAAU;AAC9B;AAmBO,SAAS,aAAa,KAAsB;AAEjD,MAAI,IAAI,WAAW,EAAG,QAAO;AAG7B,MAAI,KAAK,KAAK,GAAG,EAAG,QAAO;AAI3B,MAAI,gBAAgB,GAAG,EAAG,QAAO;AAGjC,MAAI,QAAQ,OAAO,QAAQ,OAAO,QAAQ,UAAU,QAAQ,QAAS,QAAO;AAG5E,MAAI,QAAQ,OAAO,QAAQ,UAAU,QAAQ,YAAa,QAAO;AAGjE,MAAI,aAAa,KAAK,GAAG,EAAG,QAAO;AAGnC,MAAI,gBAAgB,KAAK,GAAG,EAAG,QAAO;AAGtC,SAAO;AACT;AAMA,SAAS,gBAAgB,KAAsB;AAC7C,MAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,QAAM,QAAQ,IAAI,CAAC;AACnB,MAAI,UAAU,OAAO,UAAU,KAAK;AAClC,QAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,UAAM,SAAS,IAAI,CAAC;AACpB,WAAQ,UAAU,OAAO,UAAU,OAAQ,WAAW;AAAA,EACxD;AACA,MAAI,UAAU,KAAK;AACjB,QAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,UAAM,SAAS,IAAI,CAAC;AACpB,WAAO,UAAU,OAAO,UAAU;AAAA,EACpC;AACA,SAAO,SAAS,OAAO,SAAS;AAClC;AASO,SAAS,aAAa,KAAa,WAAmB,KAAa;AACxE,SAAO,IACJ,QAAQ,OAAO,MAAM,EACrB,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,KAAK,EACpB,QAAQ,IAAI,OAAO,UAAU,GAAG,GAAG,OAAO,QAAQ;AACvD;AAQO,SAAS,eAAe,KAAqB;AAClD,SAAO,IACJ,QAAQ,QAAQ,IAAI,EACpB,QAAQ,QAAQ,IAAI,EACpB,QAAQ,QAAQ,GAAI,EACpB,QAAQ,QAAQ,GAAG,EACnB,QAAQ,QAAQ,GAAG,EACnB,QAAQ,SAAS,IAAI;AAC1B;AASO,SAAS,kBAAkB,KAAqB;AACrD,SAAO,YAAY,KAAK,WAAW,gDAAiB,OAAO;AAC7D;AASO,SAAS,yBAAyB,KAAqB;AAC5D,SAAO,YAAY,KAAK,QAAQ,gDAAiB,OAAO;AAC1D;","names":["TypedefRegistry"]}