Home Manual Reference Source Test Repository

lib/data-files.js

  1. import path from 'path';
  2. import _ from 'lodash';
  3. import Promise from 'bluebird';
  4. import glob from 'glob';
  5. import Parse from './parse';
  6.  
  7. /**
  8. * Load all files in the given dataPath file and parse them into a JS object.
  9. * Then depending on the directory path structure and the name of the file
  10. * set the files contents in that path on an object.
  11. * @param {string} dataPath Path to data files.
  12. * @return {Object}
  13. */
  14. export async function readDataFiles(dataPath = '') {
  15. // Read all files from disk and get their file paths.
  16. const filePaths = await Promise.fromCallback(cb => {
  17. glob(
  18. `${dataPath}/**/*.{json,yml,yaml}`,
  19. {
  20. // Do not match directories, only files.
  21. nodir: true,
  22. // Follow symlinks.
  23. follow: true,
  24. },
  25. cb
  26. );
  27. }).map(filePath =>
  28. // Correct the filePath created by glob to be compatible with Windows.
  29. // Known issue in node-glob https://github.com/isaacs/node-glob/pull/263.
  30. // eslint-disable-next-line no-useless-escape
  31. path.normalize(filePath.replace(/[\\\/]/g, path.sep))
  32. );
  33.  
  34. const files = filePaths.map(filePath => ({
  35. filePath,
  36. // Load and parse file's contents.
  37. content: Parse.smartLoadAndParse(filePath),
  38. // Create the path where we'll set the file's contents.
  39. // This turns something like
  40. // /Users/user/reptar/_data/friends/angelica.json
  41. // into
  42. // ['friends', 'angelica']
  43. // So we can use it with _.set.
  44. dataPath: path
  45. .relative(
  46. dataPath,
  47. path.join(
  48. path.dirname(filePath),
  49. path.basename(filePath, path.extname(filePath))
  50. )
  51. )
  52. .split(path.sep),
  53. }));
  54.  
  55. return files.reduce(
  56. (acc, file) =>
  57. // Set file's contents on the corresponding path.
  58. _.set(acc, file.dataPath, file.content),
  59. {}
  60. );
  61. }
  62.  
  63. export default async function addDataFiles(reptar) {
  64. // Read data files.
  65. const dataFiles = await readDataFiles(reptar.config.get('path.data'));
  66.  
  67. // Expose it on the site object.
  68. reptar.metadata.set('site.data', dataFiles);
  69. }