{"version":3,"sources":["../../../src/schema/types/string.ts"],"sourcesContent":["import Definitions          from '../../core/definitions'\r\nimport ValidationError      from '../../errors/io-validation-error'\r\nimport ErrorCodes           from '../../errors/io-error-codes'\r\nimport Node                 from '../../parser/nodes/nodes'\r\nimport TokenNode            from '../../parser/nodes/tokens'\r\nimport TypeDef              from '../../schema/typedef'\r\nimport TokenType            from '../../parser/tokenizer/token-types'\r\nimport Schema               from '../../schema/schema'\r\nimport * as strings         from '../../utils/strings'\r\nimport MemberDef            from './memberdef'\r\nimport doCommonTypeCheck    from './common-type'\r\n\r\nconst STRING_TYPES = ['string', 'url', 'email']\r\n\r\n// Reference: RFC 5322 Official Standard\r\n// http://emailregex.com\r\nconst emailExp = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])/\r\n\r\n// http://urlregex.com\r\nconst urlExp = /((([A-Za-z]{3,9}:(?:\\/\\/)?)(?:[\\-;:&=\\+\\$,\\w]+@)?[A-Za-z0-9\\.\\-]+|(?:www\\.|[\\-;:&=\\+\\$,\\w]+@)[A-Za-z0-9\\.\\-]+)((?:\\/[\\+~%\\/\\.\\w\\-_]*)?\\??(?:[\\-\\+=&;%@\\.\\w_]*)#?(?:[\\.\\!\\/\\\\\\w]*))?)/\r\n\r\nconst schema = new Schema(\r\n  \"string\",\r\n  { type:             { type: \"string\", optional: false, null: false, choices: STRING_TYPES } },\r\n  { default:          { type: \"string\", optional: true,  null: false  } },\r\n  { choices:          { type: \"array\",  optional: true,  null: false, of: { type: \"string\" } } },\r\n  { pattern:          { type: \"string\", optional: true,  null: false  } },\r\n  { flags:            { type: \"string\", optional: true,  null: false } },\r\n  { len:              { type: \"number\", optional: true,  null: false, min: 0 } },\r\n  { minLen:           { type: \"number\", optional: true,  null: false, min: 0 } },\r\n  { maxLen:           { type: \"number\", optional: true,  null: false, min: 0 } },\r\n  { format:           { type: \"string\", optional: true, null: false, choices: [\"auto\", \"regular\", \"raw\"], default:\"auto\" } },\r\n  { escapeLines:      { type: \"bool\",   optional: true, null: false, default: false } },\r\n  { encloser :        { type: \"string\", optional: true, null: false, choices: ['\"', \"'\"], default: '\"' } },\r\n  { optional:         { type: \"bool\",   optional: true } },\r\n  { null:             { type: \"bool\",   optional: true } },\r\n)\r\n\r\n/**\r\n * Represents the StringTypeDef which is reponsible for parsing,\r\n * validating, loading and serializing strings.\r\n *\r\n * It performs the following validation\r\n * - Value is string\r\n* - Value is optional\r\n* - Value is null\r\n* - Value is in choices\r\n * - Value length <= maxLength\r\n * - Value length >= minLen\r\n */\r\nexport default class StringDef implements TypeDef {\r\n  private _type: string\r\n\r\n  constructor(type: string = 'string') {\r\n    this._type = type\r\n  }\r\n\r\n  get type() { return this._type }\r\n\r\n  static get types() { return STRING_TYPES }\r\n\r\n  get schema() { return schema }\r\n\r\n  /**\r\n   * Parses the string in IO format into JavaScript strings.\r\n   */\r\n  parse(valueNode: Node, memberDef: MemberDef, defs?: Definitions): string {\r\n    return _process(valueNode, memberDef, defs)\r\n  }\r\n\r\n  /** Load: JS Value → Validated JS Value */\r\n  load(value: any, memberDef: MemberDef, defs?: Definitions): string {\r\n    const { value: checkedValue, changed } = doCommonTypeCheck(memberDef, value, undefined, defs)\r\n    if (changed) return checkedValue\r\n    // Type check\r\n    if (typeof value !== 'string') {\r\n      throw new ValidationError(ErrorCodes.notAString, `Expecting a string value for '${memberDef.path}' but found ${JSON.stringify(value)}.`)\r\n    }\r\n    // Shared validations\r\n    _validatePattern(memberDef, value)\r\n    // Len checks\r\n    const len = memberDef.len\r\n    if (len !== undefined && typeof len === 'number' && value.length !== len) {\r\n      throw new ValidationError(ErrorCodes.invalidLength, `Invalid length for ${memberDef.path}.`)\r\n    }\r\n    const maxLen = memberDef.maxLen\r\n    if (maxLen !== undefined && typeof maxLen === 'number' && value.length > maxLen) {\r\n      throw new ValidationError(ErrorCodes.invalidMaxLength, `Invalid maxLength for ${memberDef.path}.`)\r\n    }\r\n    const minLen = memberDef.minLen\r\n    if (minLen !== undefined && typeof minLen === 'number' && value.length < minLen) {\r\n      throw new ValidationError(ErrorCodes.invalidMinLength, `Invalid minLength for ${memberDef.path}.`)\r\n    }\r\n    return value\r\n  }\r\n\r\n  stringify(value: string, memberDef: MemberDef): string {\r\n    // Validate before formatting to ensure consistency\r\n    this.load(value, memberDef)\r\n    const format = memberDef.format || 'auto'\r\n    switch (format) {\r\n      case 'auto':\r\n        // Smart output: tries unquoted first, quotes when needed (ambiguous values,\r\n        // commas), uses raw for strings with many escape chars. Never breaks round-trip.\r\n        return strings.toAutoString(value, memberDef.escapeLines, memberDef.encloser)\r\n\r\n      case 'regular':\r\n        // Always quoted: \"value\"\r\n        return strings.toRegularString(value, memberDef.escapeLines, memberDef.encloser)\r\n\r\n      case 'raw':\r\n        // Always raw: r\"value\"\r\n        return strings.toRawString(value, memberDef.encloser)\r\n\r\n      default:\r\n        // Fallback to auto for any unknown format\r\n        return strings.toAutoString(value, memberDef.escapeLines, memberDef.encloser)\r\n    }\r\n  }\r\n}\r\n\r\nfunction _process(node: Node, memberDef: MemberDef, defs?: Definitions): string {\r\n  const valueNode = defs?.getV(node) || node\r\n  const { value, changed } = doCommonTypeCheck(memberDef, valueNode, node, defs)\r\n  if (changed) return value\r\n\r\n  if (valueNode instanceof TokenNode === false || valueNode.type !== TokenType.STRING) {\r\n    throw new ValidationError(ErrorCodes.notAString,\r\n      `Expecting a string value for '${memberDef.path}' but found ${valueNode.toValue()}.`,\r\n      node)\r\n  }\r\n\r\n  _validatePattern(memberDef, value, node)\r\n\r\n\r\n  // Len check\r\n  const len = memberDef.len\r\n  if (len !== undefined && typeof len === 'number') {\r\n    if (value.length !== len) {\r\n      throw new ValidationError(\r\n        ErrorCodes.invalidLength,\r\n        `Invalid length for ${memberDef.path}.`, valueNode\r\n      )\r\n    }\r\n  }\r\n\r\n  // Max length check\r\n  const maxLen = memberDef.maxLen\r\n  if (maxLen !== undefined && typeof maxLen === 'number') {\r\n    if (value.length > maxLen) {\r\n      throw new ValidationError(\r\n        ErrorCodes.invalidMaxLength,\r\n        `Invalid maxLength for ${memberDef.path}.`, valueNode\r\n        )\r\n      }\r\n    }\r\n\r\n    // Max length check\r\n    const minLen = memberDef.minLen\r\n    if (minLen !== undefined && typeof minLen === 'number') {\r\n    if (value.length < minLen) {\r\n      throw new ValidationError(\r\n        ErrorCodes.invalidMinLength,\r\n        `Invalid minLen for ${memberDef.path}.`, valueNode\r\n      )\r\n    }\r\n  }\r\n  return value\r\n}\r\n\r\nfunction _validatePattern(memberDef: MemberDef, value: string, node?: Node) {\r\n  const type = memberDef.type\r\n\r\n  // Validate user defined pattern\r\n  if (type === 'string' && memberDef.pattern !== undefined) {\r\n    let re = memberDef.re\r\n    if (!re) {\r\n      let pattern = memberDef.pattern\r\n      let flags = memberDef.flags\r\n\r\n      // Compile the expression and cache it into the memberDef\r\n      try {\r\n        if (flags) {\r\n          re = memberDef.re = new RegExp(pattern, flags)\r\n        } else {\r\n          re = memberDef.re = new RegExp(pattern)\r\n        }\r\n        memberDef.re = re // Cache the compiled expression\r\n      } catch {\r\n        throw new ValidationError(ErrorCodes.invalidPattern, value, node)\r\n      }\r\n    }\r\n    if (!re.test(value)) {\r\n      throw new ValidationError(ErrorCodes.invalidPattern,\r\n        `The value '${value}' does not match the pattern '${memberDef.pattern}'.`, node)\r\n    }\r\n  }\r\n  // Validate email\r\n  else if (type === 'email') {\r\n    if (!emailExp.test(value)) {\r\n      throw new ValidationError(ErrorCodes.invalidEmail, `Invalid email address: ${value}`, node)\r\n    }\r\n  }\r\n  // Validate url\r\n  else if (type === 'url') {\r\n    if (!urlExp.test(value)) {\r\n      throw new ValidationError(ErrorCodes.invalidUrl, `Invalid URL: ${value}`, node)\r\n    }\r\n  }\r\n}\r\n"],"mappings":"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","names":["Schema","doCommonTypeCheck","ValidationError","ErrorCodes","TokenNode","TokenType"]}