parse-field.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. "use strict";
  2. const path = require("path");
  3. const envReplace = require("./env-replace");
  4. const types = require("./types");
  5. module.exports = parseField;
  6. // https://github.com/npm/npm/blob/latest/lib/config/core.js#L362-L407
  7. function parseField(input, key) {
  8. if (typeof input !== "string") {
  9. return input;
  10. }
  11. const typeList = [].concat(types[key]);
  12. const isPath = typeList.indexOf(path) !== -1;
  13. const isBool = typeList.indexOf(Boolean) !== -1;
  14. const isString = typeList.indexOf(String) !== -1;
  15. const isNumber = typeList.indexOf(Number) !== -1;
  16. let field = `${input}`.trim();
  17. if (/^".*"$/.test(field)) {
  18. try {
  19. field = JSON.parse(field);
  20. } catch (err) {
  21. throw new Error(`Failed parsing JSON config key ${key}: ${field}`);
  22. }
  23. }
  24. if (isBool && !isString && field === "") {
  25. return true;
  26. }
  27. switch (field) {
  28. case "true": {
  29. return true;
  30. }
  31. case "false": {
  32. return false;
  33. }
  34. case "null": {
  35. return null;
  36. }
  37. case "undefined": {
  38. return undefined;
  39. }
  40. // no default
  41. }
  42. field = envReplace(field);
  43. if (isPath) {
  44. const regex = process.platform === "win32" ? /^~(\/|\\)/ : /^~\//;
  45. if (regex.test(field) && process.env.HOME) {
  46. field = path.resolve(process.env.HOME, field.substr(2));
  47. }
  48. field = path.resolve(field);
  49. }
  50. // eslint-disable-next-line no-restricted-globals
  51. if (isNumber && !isNaN(field)) {
  52. field = Number(field);
  53. }
  54. return field;
  55. }