index.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.extract = extract;
  6. exports.parse = parse;
  7. exports.parseWithComments = parseWithComments;
  8. exports.print = print;
  9. exports.strip = strip;
  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 =
  39. /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *(?![^@\r\n]*\/\/[^]*)([^@\r\n\s][^@\r\n]+?) *\r?\n/g;
  40. const propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g;
  41. const stringStartRe = /(\r?\n|^) *\* ?/g;
  42. const STRING_ARRAY = [];
  43. function extract(contents) {
  44. const match = contents.match(docblockRe);
  45. return match ? match[0].trimLeft() : '';
  46. }
  47. function strip(contents) {
  48. const match = contents.match(docblockRe);
  49. return match && match[0] ? contents.substring(match[0].length) : contents;
  50. }
  51. function parse(docblock) {
  52. return parseWithComments(docblock).pragmas;
  53. }
  54. function parseWithComments(docblock) {
  55. const line = (0, _detectNewline().default)(docblock) || _os().EOL;
  56. docblock = docblock
  57. .replace(commentStartRe, '')
  58. .replace(commentEndRe, '')
  59. .replace(stringStartRe, '$1'); // Normalize multi-line directives
  60. let prev = '';
  61. while (prev !== docblock) {
  62. prev = docblock;
  63. docblock = docblock.replace(multilineRe, `${line}$1 $2${line}`);
  64. }
  65. docblock = docblock.replace(ltrimNewlineRe, '').trimRight();
  66. const result = Object.create(null);
  67. const comments = docblock
  68. .replace(propertyRe, '')
  69. .replace(ltrimNewlineRe, '')
  70. .trimRight();
  71. let match;
  72. while ((match = propertyRe.exec(docblock))) {
  73. // strip linecomments from pragmas
  74. const nextPragma = match[2].replace(lineCommentRe, '');
  75. if (
  76. typeof result[match[1]] === 'string' ||
  77. Array.isArray(result[match[1]])
  78. ) {
  79. result[match[1]] = STRING_ARRAY.concat(result[match[1]], nextPragma);
  80. } else {
  81. result[match[1]] = nextPragma;
  82. }
  83. }
  84. return {
  85. comments,
  86. pragmas: result
  87. };
  88. }
  89. function print({comments = '', pragmas = {}}) {
  90. const line = (0, _detectNewline().default)(comments) || _os().EOL;
  91. const head = '/**';
  92. const start = ' *';
  93. const tail = ' */';
  94. const keys = Object.keys(pragmas);
  95. const printedObject = keys
  96. .map(key => printKeyValues(key, pragmas[key]))
  97. .reduce((arr, next) => arr.concat(next), [])
  98. .map(keyValue => start + ' ' + keyValue + line)
  99. .join('');
  100. if (!comments) {
  101. if (keys.length === 0) {
  102. return '';
  103. }
  104. if (keys.length === 1 && !Array.isArray(pragmas[keys[0]])) {
  105. const value = pragmas[keys[0]];
  106. return `${head} ${printKeyValues(keys[0], value)[0]}${tail}`;
  107. }
  108. }
  109. const printedComments =
  110. comments
  111. .split(line)
  112. .map(textLine => `${start} ${textLine}`)
  113. .join(line) + line;
  114. return (
  115. head +
  116. line +
  117. (comments ? printedComments : '') +
  118. (comments && keys.length ? start + line : '') +
  119. printedObject +
  120. tail
  121. );
  122. }
  123. function printKeyValues(key, valueOrArray) {
  124. return STRING_ARRAY.concat(valueOrArray).map(value =>
  125. `@${key} ${value}`.trim()
  126. );
  127. }