getFromStreamChunks.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const createMappingsSerializer = require("./createMappingsSerializer");
  7. /** @typedef {import("../Source").RawSourceMap} RawSourceMap */
  8. /** @typedef {import("../Source").SourceAndMap} SourceAndMap */
  9. /** @typedef {import("./streamChunks").Options} Options */
  10. /** @typedef {import("./streamChunks").StreamChunksFunction} StreamChunksFunction */
  11. /** @typedef {{ streamChunks: StreamChunksFunction }} SourceLikeWithStreamChunks */
  12. /**
  13. * @param {SourceLikeWithStreamChunks} inputSource input source
  14. * @param {Options=} options options
  15. * @returns {SourceAndMap} map
  16. */
  17. module.exports.getSourceAndMap = (inputSource, options) => {
  18. let code = "";
  19. let mappings = "";
  20. /** @type {(string | null)[]} */
  21. const potentialSources = [];
  22. /** @type {(string | null)[]} */
  23. const potentialSourcesContent = [];
  24. /** @type {(string | null)[]} */
  25. const potentialNames = [];
  26. const addMapping = createMappingsSerializer(options);
  27. const { source } = inputSource.streamChunks(
  28. { ...options, finalSource: true },
  29. (
  30. chunk,
  31. generatedLine,
  32. generatedColumn,
  33. sourceIndex,
  34. originalLine,
  35. originalColumn,
  36. nameIndex,
  37. ) => {
  38. if (chunk !== undefined) code += chunk;
  39. mappings += addMapping(
  40. generatedLine,
  41. generatedColumn,
  42. sourceIndex,
  43. originalLine,
  44. originalColumn,
  45. nameIndex,
  46. );
  47. },
  48. (sourceIndex, source, sourceContent) => {
  49. while (potentialSources.length < sourceIndex) {
  50. potentialSources.push(null);
  51. }
  52. potentialSources[sourceIndex] = source;
  53. if (sourceContent !== undefined) {
  54. while (potentialSourcesContent.length < sourceIndex) {
  55. potentialSourcesContent.push(null);
  56. }
  57. potentialSourcesContent[sourceIndex] = sourceContent;
  58. }
  59. },
  60. (nameIndex, name) => {
  61. while (potentialNames.length < nameIndex) {
  62. potentialNames.push(null);
  63. }
  64. potentialNames[nameIndex] = name;
  65. },
  66. );
  67. return {
  68. source: source !== undefined ? source : code,
  69. map:
  70. mappings.length > 0
  71. ? {
  72. version: 3,
  73. file: "x",
  74. mappings,
  75. // We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change
  76. sources: /** @type {string[]} */ (potentialSources),
  77. sourcesContent:
  78. potentialSourcesContent.length > 0
  79. ? /** @type {string[]} */ (potentialSourcesContent)
  80. : undefined,
  81. names: /** @type {string[]} */ (potentialNames),
  82. }
  83. : null,
  84. };
  85. };
  86. /**
  87. * @param {SourceLikeWithStreamChunks} source source
  88. * @param {Options=} options options
  89. * @returns {RawSourceMap | null} map
  90. */
  91. module.exports.getMap = (source, options) => {
  92. let mappings = "";
  93. /** @type {(string | null)[]} */
  94. const potentialSources = [];
  95. /** @type {(string | null)[]} */
  96. const potentialSourcesContent = [];
  97. /** @type {(string | null)[]} */
  98. const potentialNames = [];
  99. const addMapping = createMappingsSerializer(options);
  100. source.streamChunks(
  101. { ...options, source: false, finalSource: true },
  102. (
  103. chunk,
  104. generatedLine,
  105. generatedColumn,
  106. sourceIndex,
  107. originalLine,
  108. originalColumn,
  109. nameIndex,
  110. ) => {
  111. mappings += addMapping(
  112. generatedLine,
  113. generatedColumn,
  114. sourceIndex,
  115. originalLine,
  116. originalColumn,
  117. nameIndex,
  118. );
  119. },
  120. (sourceIndex, source, sourceContent) => {
  121. while (potentialSources.length < sourceIndex) {
  122. potentialSources.push(null);
  123. }
  124. potentialSources[sourceIndex] = source;
  125. if (sourceContent !== undefined) {
  126. while (potentialSourcesContent.length < sourceIndex) {
  127. potentialSourcesContent.push(null);
  128. }
  129. potentialSourcesContent[sourceIndex] = sourceContent;
  130. }
  131. },
  132. (nameIndex, name) => {
  133. while (potentialNames.length < nameIndex) {
  134. potentialNames.push(null);
  135. }
  136. potentialNames[nameIndex] = name;
  137. },
  138. );
  139. return mappings.length > 0
  140. ? {
  141. version: 3,
  142. file: "x",
  143. mappings,
  144. // We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change
  145. sources: /** @type {string[]} */ (potentialSources),
  146. sourcesContent:
  147. potentialSourcesContent.length > 0
  148. ? /** @type {string[]} */ (potentialSourcesContent)
  149. : undefined,
  150. names: /** @type {string[]} */ (potentialNames),
  151. }
  152. : null;
  153. };