loadDefinedFile.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //
  2. 'use strict';
  3. const yaml = require('js-yaml');
  4. const requireFromString = require('require-from-string');
  5. const readFile = require('./readFile');
  6. const parseJson = require('./parseJson');
  7. const path = require('path');
  8. module.exports = function loadDefinedFile(
  9. filepath ,
  10. options
  11. ) {
  12. function parseContent(content ) {
  13. if (!content) {
  14. throw new Error(`Config file is empty! Filepath - "${filepath}".`);
  15. }
  16. let parsedConfig;
  17. switch (options.format || inferFormat(filepath)) {
  18. case 'json':
  19. parsedConfig = parseJson(content, filepath);
  20. break;
  21. case 'yaml':
  22. parsedConfig = yaml.safeLoad(content, {
  23. filename: filepath,
  24. });
  25. break;
  26. case 'js':
  27. parsedConfig = requireFromString(content, filepath);
  28. break;
  29. default:
  30. parsedConfig = tryAllParsing(content, filepath);
  31. }
  32. if (!parsedConfig) {
  33. throw new Error(`Failed to parse "${filepath}" as JSON, JS, or YAML.`);
  34. }
  35. return {
  36. config: parsedConfig,
  37. filepath,
  38. };
  39. }
  40. return !options.sync
  41. ? readFile(filepath, { throwNotFound: true }).then(parseContent)
  42. : parseContent(readFile.sync(filepath, { throwNotFound: true }));
  43. };
  44. function inferFormat(filepath ) {
  45. switch (path.extname(filepath)) {
  46. case '.js':
  47. return 'js';
  48. case '.json':
  49. return 'json';
  50. // istanbul ignore next
  51. case '.yml':
  52. case '.yaml':
  53. return 'yaml';
  54. default:
  55. return undefined;
  56. }
  57. }
  58. function tryAllParsing(content , filepath ) {
  59. return tryYaml(content, filepath, () => {
  60. return tryRequire(content, filepath, () => {
  61. return null;
  62. });
  63. });
  64. }
  65. function tryYaml(content , filepath , cb ) {
  66. try {
  67. const result = yaml.safeLoad(content, {
  68. filename: filepath,
  69. });
  70. if (typeof result === 'string') {
  71. return cb();
  72. }
  73. return result;
  74. } catch (e) {
  75. return cb();
  76. }
  77. }
  78. function tryRequire(content , filepath , cb ) {
  79. try {
  80. return requireFromString(content, filepath);
  81. } catch (e) {
  82. return cb();
  83. }
  84. }