mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 19:07:23 +00:00

PR-URL: https://github.com/nodejs/node/pull/42744 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
82 lines
2.1 KiB
JavaScript
82 lines
2.1 KiB
JavaScript
// Parse a field, coercing it to the best type available.
|
|
const typeDefs = require('./type-defs.js')
|
|
const envReplace = require('./env-replace.js')
|
|
const { resolve } = require('path')
|
|
|
|
const { parse: umaskParse } = require('./umask.js')
|
|
|
|
const parseField = (f, key, opts, listElement = false) => {
|
|
if (typeof f !== 'string' && !Array.isArray(f)) {
|
|
return f
|
|
}
|
|
|
|
const { platform, types, home, env } = opts
|
|
|
|
// type can be array or a single thing. coerce to array.
|
|
const typeList = new Set([].concat(types[key]))
|
|
const isPath = typeList.has(typeDefs.path.type)
|
|
const isBool = typeList.has(typeDefs.Boolean.type)
|
|
const isString = isPath || typeList.has(typeDefs.String.type)
|
|
const isUmask = typeList.has(typeDefs.Umask.type)
|
|
const isNumber = typeList.has(typeDefs.Number.type)
|
|
const isList = !listElement && typeList.has(Array)
|
|
|
|
if (Array.isArray(f)) {
|
|
return !isList ? f : f.map(field => parseField(field, key, opts, true))
|
|
}
|
|
|
|
// now we know it's a string
|
|
f = f.trim()
|
|
|
|
// list types get put in the environment separated by double-\n
|
|
// usually a single \n would suffice, but ca/cert configs can contain
|
|
// line breaks and multiple entries.
|
|
if (isList) {
|
|
return parseField(f.split('\n\n'), key, opts)
|
|
}
|
|
|
|
// --foo is like --foo=true for boolean types
|
|
if (isBool && !isString && f === '') {
|
|
return true
|
|
}
|
|
|
|
// string types can be the string 'true', 'false', etc.
|
|
// otherwise, parse these values out
|
|
if (!isString && !isPath && !isNumber) {
|
|
switch (f) {
|
|
case 'true': return true
|
|
case 'false': return false
|
|
case 'null': return null
|
|
case 'undefined': return undefined
|
|
}
|
|
}
|
|
|
|
f = envReplace(f, env)
|
|
|
|
if (isPath) {
|
|
const homePattern = platform === 'win32' ? /^~(\/|\\)/ : /^~\//
|
|
if (homePattern.test(f) && home) {
|
|
f = resolve(home, f.slice(2))
|
|
} else {
|
|
f = resolve(f)
|
|
}
|
|
}
|
|
|
|
if (isUmask) {
|
|
try {
|
|
return umaskParse(f)
|
|
} catch (er) {
|
|
// let it warn later when we validate
|
|
return f
|
|
}
|
|
}
|
|
|
|
if (isNumber && !isNaN(f)) {
|
|
f = +f
|
|
}
|
|
|
|
return f
|
|
}
|
|
|
|
module.exports = parseField
|