integration-docs-fetch-plugin.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*eslint-env node*/
  2. /*eslint import/no-nodejs-modules:0 */
  3. const fs = require('fs');
  4. const https = require('https');
  5. const path = require('path');
  6. const PLATFORMS_URL = 'https://docs.sentry.io/_platforms/_index.json';
  7. const DOCS_INDEX_PATH = 'src/sentry/integration-docs/_platforms.json';
  8. const alphaSortFromKey = keyExtractor => (a, b) =>
  9. keyExtractor(a).localeCompare(keyExtractor(b));
  10. const transformPlatformsToList = ({platforms}) =>
  11. Object.keys(platforms)
  12. .map(platformId => {
  13. const integrationMap = platforms[platformId];
  14. const integrations = Object.keys(integrationMap)
  15. .sort(alphaSortFromKey(key => integrationMap[key].name))
  16. .map(integrationId => {
  17. const {name, type, doc_link: link} = integrationMap[integrationId];
  18. const id =
  19. integrationId === '_self' ? platformId : `${platformId}-${integrationId}`;
  20. return {id, name, type, link};
  21. });
  22. return {
  23. id: platformId,
  24. name: integrationMap._self.name,
  25. integrations,
  26. };
  27. })
  28. .sort(alphaSortFromKey(item => item.name));
  29. function fetch(_compilation, callback) {
  30. https
  31. .get(PLATFORMS_URL, res => {
  32. res.setEncoding('utf8');
  33. let buffer = '';
  34. res
  35. .on('data', data => {
  36. buffer += data;
  37. })
  38. .on('end', () =>
  39. fs.writeFile(
  40. this.modulePath,
  41. JSON.stringify({
  42. platforms: transformPlatformsToList(JSON.parse(buffer)),
  43. }),
  44. callback
  45. )
  46. );
  47. })
  48. .on('error', callback);
  49. }
  50. class IntegrationDocsFetchPlugin {
  51. constructor({basePath}) {
  52. this.modulePath = path.join(basePath, DOCS_INDEX_PATH);
  53. this.hasRun = false;
  54. const moduleDir = path.dirname(this.modulePath);
  55. if (!fs.existsSync(moduleDir)) {
  56. fs.mkdirSync(moduleDir, {recursive: true});
  57. }
  58. }
  59. apply(compiler) {
  60. compiler.hooks.beforeRun.tapAsync('IntegrationDocsFetchPlugin', fetch.bind(this));
  61. compiler.hooks.watchRun.tapAsync(
  62. 'IntegrationDocsFetchPlugin',
  63. (compilation, callback) => {
  64. // Only run once when watching and only if it does not exist on fs
  65. if (this.hasRun || fs.existsSync(this.modulePath)) {
  66. callback();
  67. return;
  68. }
  69. fetch.call(this, compilation, callback);
  70. this.hasRun = true;
  71. }
  72. );
  73. }
  74. }
  75. module.exports = IntegrationDocsFetchPlugin;