index.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.extract = extract;
  6. exports.strip = strip;
  7. exports.parse = parse;
  8. exports.parseWithComments = parseWithComments;
  9. exports.print = print;
  10. function _os() {
  11. const data = require('os');
  12. _os = function () {
  13. return data;
  14. };
  15. return data;
  16. }
  17. function _detectNewline() {
  18. const data = _interopRequireDefault(require('detect-newline'));
  19. _detectNewline = function () {
  20. return data;
  21. };
  22. return data;
  23. }
  24. function _interopRequireDefault(obj) {
  25. return obj && obj.__esModule ? obj : {default: obj};
  26. }
  27. /**
  28. * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  29. *
  30. * This source code is licensed under the MIT license found in the
  31. * LICENSE file in the root directory of this source tree.
  32. */
  33. const commentEndRe = /\*\/$/;
  34. const commentStartRe = /^\/\*\*/;
  35. const docblockRe = /^\s*(\/\*\*?(.|\r?\n)*?\*\/)/;
  36. const lineCommentRe = /(^|\s+)\/\/([^\r\n]*)/g;
  37. const ltrimNewlineRe = /^(\r?\n)+/;
  38. const multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *(?![^@\r\n]*\/\/[^]*)([^@\r\n\s][^@\r\n]+?) *\r?\n/g;
  39. const propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g;
  40. const stringStartRe = /(\r?\n|^) *\* ?/g;
  41. const STRING_ARRAY = [];
  42. function extract(contents) {
  43. const match = contents.match(docblockRe);
  44. return match ? match[0].trimLeft() : '';
  45. }
  46. function strip(contents) {
  47. const match = contents.match(docblockRe);
  48. return match && match[0] ? contents.substring(match[0].length) : contents;
  49. }
  50. function parse(docblock) {
  51. return parseWithComments(docblock).pragmas;
  52. }
  53. function parseWithComments(docblock) {
  54. const line = (0, _detectNewline().default)(docblock) || _os().EOL;
  55. docblock = docblock
  56. .replace(commentStartRe, '')
  57. .replace(commentEndRe, '')
  58. .replace(stringStartRe, '$1'); // Normalize multi-line directives
  59. let prev = '';
  60. while (prev !== docblock) {
  61. prev = docblock;
  62. docblock = docblock.replace(multilineRe, `${line}$1 $2${line}`);
  63. }
  64. docblock = docblock.replace(ltrimNewlineRe, '').trimRight();
  65. const result = Object.create(null);
  66. const comments = docblock
  67. .replace(propertyRe, '')
  68. .replace(ltrimNewlineRe, '')
  69. .trimRight();
  70. let match;
  71. while ((match = propertyRe.exec(docblock))) {
  72. // strip linecomments from pragmas
  73. const nextPragma = match[2].replace(lineCommentRe, '');
  74. if (
  75. typeof result[match[1]] === 'string' ||
  76. Array.isArray(result[match[1]])
  77. ) {
  78. result[match[1]] = STRING_ARRAY.concat(result[match[1]], nextPragma);
  79. } else {
  80. result[match[1]] = nextPragma;
  81. }
  82. }
  83. return {
  84. comments,
  85. pragmas: result
  86. };
  87. }
  88. function print({comments = '', pragmas = {}}) {
  89. const line = (0, _detectNewline().default)(comments) || _os().EOL;
  90. const head = '/**';
  91. const start = ' *';
  92. const tail = ' */';
  93. const keys = Object.keys(pragmas);
  94. const printedObject = keys
  95. .map(key => printKeyValues(key, pragmas[key]))
  96. .reduce((arr, next) => arr.concat(next), [])
  97. .map(keyValue => start + ' ' + keyValue + line)
  98. .join('');
  99. if (!comments) {
  100. if (keys.length === 0) {
  101. return '';
  102. }
  103. if (keys.length === 1 && !Array.isArray(pragmas[keys[0]])) {
  104. const value = pragmas[keys[0]];
  105. return `${head} ${printKeyValues(keys[0], value)[0]}${tail}`;
  106. }
  107. }
  108. const printedComments =
  109. comments
  110. .split(line)
  111. .map(textLine => `${start} ${textLine}`)
  112. .join(line) + line;
  113. return (
  114. head +
  115. line +
  116. (comments ? printedComments : '') +
  117. (comments && keys.length ? start + line : '') +
  118. printedObject +
  119. tail
  120. );
  121. }
  122. function printKeyValues(key, valueOrArray) {
  123. return STRING_ARRAY.concat(valueOrArray).map(value =>
  124. `@${key} ${value}`.trim()
  125. );
  126. }