11cb0ef41Sopenharmony_ciconst SemVer = require('../classes/semver')
21cb0ef41Sopenharmony_ciconst parse = require('./parse')
31cb0ef41Sopenharmony_ciconst { safeRe: re, t } = require('../internal/re')
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst coerce = (version, options) => {
61cb0ef41Sopenharmony_ci  if (version instanceof SemVer) {
71cb0ef41Sopenharmony_ci    return version
81cb0ef41Sopenharmony_ci  }
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci  if (typeof version === 'number') {
111cb0ef41Sopenharmony_ci    version = String(version)
121cb0ef41Sopenharmony_ci  }
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci  if (typeof version !== 'string') {
151cb0ef41Sopenharmony_ci    return null
161cb0ef41Sopenharmony_ci  }
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci  options = options || {}
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci  let match = null
211cb0ef41Sopenharmony_ci  if (!options.rtl) {
221cb0ef41Sopenharmony_ci    match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE])
231cb0ef41Sopenharmony_ci  } else {
241cb0ef41Sopenharmony_ci    // Find the right-most coercible string that does not share
251cb0ef41Sopenharmony_ci    // a terminus with a more left-ward coercible string.
261cb0ef41Sopenharmony_ci    // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4'
271cb0ef41Sopenharmony_ci    // With includePrerelease option set, '1.2.3.4-rc' wants to coerce '2.3.4-rc', not '2.3.4'
281cb0ef41Sopenharmony_ci    //
291cb0ef41Sopenharmony_ci    // Walk through the string checking with a /g regexp
301cb0ef41Sopenharmony_ci    // Manually set the index so as to pick up overlapping matches.
311cb0ef41Sopenharmony_ci    // Stop when we get a match that ends at the string end, since no
321cb0ef41Sopenharmony_ci    // coercible string can be more right-ward without the same terminus.
331cb0ef41Sopenharmony_ci    const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL]
341cb0ef41Sopenharmony_ci    let next
351cb0ef41Sopenharmony_ci    while ((next = coerceRtlRegex.exec(version)) &&
361cb0ef41Sopenharmony_ci        (!match || match.index + match[0].length !== version.length)
371cb0ef41Sopenharmony_ci    ) {
381cb0ef41Sopenharmony_ci      if (!match ||
391cb0ef41Sopenharmony_ci            next.index + next[0].length !== match.index + match[0].length) {
401cb0ef41Sopenharmony_ci        match = next
411cb0ef41Sopenharmony_ci      }
421cb0ef41Sopenharmony_ci      coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length
431cb0ef41Sopenharmony_ci    }
441cb0ef41Sopenharmony_ci    // leave it in a clean state
451cb0ef41Sopenharmony_ci    coerceRtlRegex.lastIndex = -1
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  if (match === null) {
491cb0ef41Sopenharmony_ci    return null
501cb0ef41Sopenharmony_ci  }
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  const major = match[2]
531cb0ef41Sopenharmony_ci  const minor = match[3] || '0'
541cb0ef41Sopenharmony_ci  const patch = match[4] || '0'
551cb0ef41Sopenharmony_ci  const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : ''
561cb0ef41Sopenharmony_ci  const build = options.includePrerelease && match[6] ? `+${match[6]}` : ''
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options)
591cb0ef41Sopenharmony_ci}
601cb0ef41Sopenharmony_cimodule.exports = coerce
61