defs.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. const dedent = require('dedent');
  2. const doctrine = require('doctrine');
  3. class Out {
  4. constructor () {
  5. this.str = '';
  6. const fn = this.out.bind(this);
  7. fn.h = this.h.bind(this);
  8. fn.lf = this.lf.bind(this);
  9. fn.text = () => this.str;
  10. return fn;
  11. }
  12. h (n, text) {
  13. this.str += '#'.repeat(n) + ' ' + text + '\n\n';
  14. }
  15. lf () { this.str += '\n'; }
  16. out (str) {
  17. this.str += str;
  18. }
  19. }
  20. class Doc {
  21. constructor () {
  22. this._construct();
  23. }
  24. provide_comment (comment) {
  25. const parsed_comment = doctrine.parse(comment.value, { unwrap: true });
  26. this.comment = parsed_comment.description;
  27. }
  28. }
  29. class ModuleDoc extends Doc {
  30. _construct () {
  31. this.services = [];
  32. this.requires = [];
  33. }
  34. add_service () {
  35. const service = new ServiceDoc();
  36. this.services.push(service);
  37. return service;
  38. }
  39. ready () {
  40. this.notes = [];
  41. const rel_requires = this.requires.filter(r => r.startsWith('../'));
  42. if ( rel_requires.length > 0 ) {
  43. this.notes.push({
  44. title: 'Outside Imports',
  45. desc: dedent(`
  46. This module has external relative imports. When these are
  47. removed it may become possible to move this module to an
  48. extension.
  49. **Imports:**
  50. ${rel_requires.map(r => {
  51. let maybe_aside = '';
  52. if ( r.endsWith('BaseService') ) {
  53. maybe_aside = ' (use.BaseService)';
  54. }
  55. return `- \`${r}\`` + maybe_aside;
  56. }).join('\n')}
  57. `)
  58. });
  59. }
  60. }
  61. toMarkdown ({ hl, out } = { hl: 1 }) {
  62. this.ready();
  63. out = out ?? new Out();
  64. out.h(hl, this.name);
  65. out(this.comment + '\n\n');
  66. if ( this.services.length > 0 ) {
  67. out.h(hl + 1, 'Services');
  68. for ( const service of this.services ) {
  69. service.toMarkdown({ out, hl: hl + 2 });
  70. }
  71. }
  72. if ( this.notes.length > 0 ) {
  73. out.h(hl + 1, 'Notes');
  74. for ( const note of this.notes ) {
  75. out.h(hl + 2, note.title);
  76. out(note.desc);
  77. out.lf();
  78. }
  79. }
  80. return out.text();
  81. }
  82. }
  83. class ServiceDoc extends Doc {
  84. _construct () {
  85. this.listeners = [];
  86. }
  87. provide_comment (comment) {
  88. const parsed_comment = doctrine.parse(comment.value, { unwrap: true });
  89. this.comment = parsed_comment.description;
  90. }
  91. provide_listener (listener) {
  92. const parsed_comment = doctrine.parse(listener.comment, { unwrap: true });
  93. const params = [];
  94. for ( const tag of parsed_comment.tags ) {
  95. if ( tag.title !== 'evtparam' ) continue;
  96. const name = tag.description.slice(0, tag.description.indexOf(' '));
  97. const desc = tag.description.slice(tag.description.indexOf(' '));
  98. params.push({ name, desc })
  99. }
  100. this.listeners.push({
  101. ...listener,
  102. comment: parsed_comment.description,
  103. params,
  104. });
  105. }
  106. toMarkdown ({ hl, out } = { hl: 1 }) {
  107. out = out ?? new Out();
  108. out.h(hl, this.name);
  109. out(this.comment + '\n\n');
  110. if ( this.listeners.length > 0 ) {
  111. out.h(hl + 1, 'Listeners');
  112. for ( const listener of this.listeners ) {
  113. out.h(hl + 2, '`' + listener.key + '`');
  114. out (listener.comment + '\n\n');
  115. if ( listener.params.length > 0 ) {
  116. out.h(hl + 3, 'Parameters');
  117. for ( const param of listener.params ) {
  118. out(`- **${param.name}:** ${param.desc}\n`);
  119. }
  120. out.lf();
  121. }
  122. }
  123. }
  124. return out.text();
  125. }
  126. }
  127. module.exports = {
  128. ModuleDoc,
  129. ServiceDoc,
  130. };