All files / key-parser value-parser.util.js

87.67% Statements 64/73
80% Branches 8/10
100% Functions 5/5
87.67% Lines 64/73

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 741x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 7x 7x 7x     7x 7x               7x 7x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 15x 15x 15x 1x 1x 1x 1x 1x 1x 1x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
import { getAST, states } from './key-ast.util.js'
import { getFormatter } from './value-formatter.js'
/** @import {Token, AST} from './key-ast.util.js' */
/** @import {TemplateFormatter} from './value-formatter.js' */
 
const tokenToString = (() => {
  /** @typedef {(token: Token) => string} TokenToString */
 
  /** @type {TokenToString[]} */
  const mapper = []
  /** @type {TokenToString} */
  const defaultMapper = (token) => token.text
  mapper[states.normal] = defaultMapper
  mapper[states.capture] = (token) => {
    const { childTokens } = token
 
    if (childTokens.length <= 0) {
      return '{}'
    }
    let normalizedCapture = tokenToString(childTokens[0])
    for (let i = 1, e = childTokens.length; i < e; i++) {
      const previousToken = childTokens[i - 1]
      const token = childTokens[i]
      if (previousToken.type === states.capture_expr && token.type === states.capture_expr) {
        normalizedCapture += ' '
      }
      normalizedCapture += tokenToString(token)
    }
    return `{${normalizedCapture}}`
  }
 
  /** @type {TokenToString} */
  const tokenToString = (token) => (mapper[token.type] ?? defaultMapper)(token)
  return tokenToString
})()
 
/**
 * Normalizes translation entry value, we use the AST instead of the text
 * to not parse it multiple times on {@link parseValue}
 * @param {AST} ast - parsed AST of the value
 * @returns {string} normalized value
 */
function getNormalizedValue (ast) {
  return ast.tokens.map((token) => tokenToString(token)).join('')
}
 
/**
 * Parses I18n translation entry value
 * @param {string} value - target i18n entry value
 * @returns {ParseResult} - parse result information
 */
export function parseValue (value) {
  const ast = getAST(value)
  const formatter = getFormatter(ast)
  const normalizedValue = getNormalizedValue(ast)
 
  return {
    value,
    ast,
    formatter,
    format: formatter.format,
    normalizedValue,
  }
}
 
/**
 * @typedef {object} ParseResult
 * @property {string} value - target value used to parse
 * @property {string} normalizedValue - normalized `value`
 * @property {TemplateFormatter} formatter - function to get the final output based on received key parameters
 * @property {TemplateFormatter['format']} format - returns the final output based on received key parameters
 * @property {AST} ast - abstract syntax tree generated by the parser, useful to debug
 */