metadata.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. var fs = require('fs');
  2. var file = require('file');
  3. var MarkdownIt = require('markdown-it');
  4. var polyfills = require('./polyfills.json');
  5. var viewRoot = fs.realpathSync(__dirname + '/../feature-detects');
  6. function metadata(cb) {
  7. var tests = [];
  8. var md = new MarkdownIt();
  9. file.walkSync(viewRoot, function(start, dirs, files) {
  10. files.forEach(function(file) {
  11. if (file === '.DS_Store') {
  12. return;
  13. }
  14. var test = fs.readFileSync(start + '/' + file, 'utf8');
  15. // TODO :: make this regex not suck
  16. var metaRE = /\/\*\!([\s\S]*)\!\*\//m;
  17. var matches = test.match(metaRE);
  18. var docRE = /\/\*\sDOC([\s\S]*?)\*\//m;
  19. var docmatches = test.match(docRE);
  20. var depRE = /define\((\[[^\]]*\]),/;
  21. var depMatches = test.match(depRE);
  22. var metadata;
  23. if (matches && matches[1]) {
  24. try {
  25. metadata = JSON.parse(matches[1]);
  26. } catch (e) {
  27. throw new Error('Error Parsing Metadata: ' + file + '\nInput: `' + matches[1] + '`');
  28. }
  29. }
  30. else {
  31. metadata = {};
  32. }
  33. var docs = null;
  34. if (docmatches && docmatches[1]) {
  35. docs = md.render(docmatches[1].trim());
  36. }
  37. metadata.doc = docs;
  38. var deps = [];
  39. var matchedDeps;
  40. if (depMatches && depMatches[1]) {
  41. try {
  42. matchedDeps = JSON.parse(depMatches[1].replace(/'/g, '"'));
  43. } catch (e) {
  44. throw new Error('Couldn\'t parse dependencies for `' + file + '`:\n`' + depMatches[1] + '\n`');
  45. }
  46. matchedDeps.forEach(function(dep) {
  47. if (dep === 'Modernizr') {
  48. return;
  49. }
  50. deps.push(dep);
  51. });
  52. } else {
  53. throw new Error('Couldn\'t find the define for `' + file + '`');
  54. }
  55. metadata.deps = deps;
  56. var baseDir = __dirname.replace(/lib$/, '');
  57. metadata.path = './' + (start + '/' + file).replace(baseDir, '').replace(/\\/g, '/');
  58. metadata.amdPath = metadata.path.replace(/^\.\/feature\-detects/, 'test').replace(/\.js$/i, '');
  59. if (!metadata.name) {
  60. metadata.name = metadata.amdPath;
  61. }
  62. var pfs = [];
  63. if (metadata.polyfills && metadata.polyfills.length) {
  64. metadata.polyfills.forEach(function(polyname) {
  65. if (polyfills[polyname]) {
  66. pfs.push(polyfills[polyname]);
  67. }
  68. else {
  69. throw new Error(metadata.name + ': Polyfill not found in `' + file + '`: ' + polyname);
  70. }
  71. });
  72. }
  73. metadata.polyfills = pfs;
  74. if (!metadata.async) {
  75. metadata.async = false;
  76. }
  77. if (!metadata.notes) {
  78. metadata.notes = [];
  79. }
  80. if (!metadata.warnings) {
  81. metadata.warnings = [];
  82. }
  83. if (!metadata.caniuse) {
  84. metadata.caniuse = null;
  85. }
  86. if (!metadata.cssclass && metadata.property) {
  87. metadata.cssclass = metadata.property;
  88. } else {
  89. metadata.cssclass = null;
  90. }
  91. // Maybe catch a bug
  92. if (!metadata.doc && metadata.docs) {
  93. metadata.doc = metadata.docs;
  94. delete metadata.docs;
  95. }
  96. // If you want markdown parsed code minus the docs and metadata, this'll do it.
  97. // Off by default for now.
  98. // metadata.code = md.render('```javascript\n' + test.replace(metaRE, '').replace(docRE, '') + '\n```');
  99. if (!metadata.tags) {
  100. metadata.tags = [];
  101. }
  102. if (!metadata.authors) {
  103. metadata.authors = [];
  104. }
  105. if (!metadata.knownBugs) {
  106. metadata.knownBugs = [];
  107. }
  108. tests.push(metadata);
  109. });
  110. });
  111. if (cb && typeof cb === 'function') {
  112. return cb(tests);
  113. }
  114. return tests;
  115. }
  116. module.exports = metadata;