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} source source
  14. * @param {Options=} options options
  15. * @returns {RawSourceMap | null} map
  16. */
  17. module.exports.getMap = (source, options) => {
  18. let mappings = "";
  19. /** @type {(string | null)[]} */
  20. const potentialSources = [];
  21. /** @type {(string | null)[]} */
  22. const potentialSourcesContent = [];
  23. /** @type {(string | null)[]} */
  24. const potentialNames = [];
  25. const addMapping = createMappingsSerializer(options);
  26. source.streamChunks(
  27. { ...options, source: false, finalSource: true },
  28. (
  29. chunk,
  30. generatedLine,
  31. generatedColumn,
  32. sourceIndex,
  33. originalLine,
  34. originalColumn,
  35. nameIndex,
  36. ) => {
  37. mappings += addMapping(
  38. generatedLine,
  39. generatedColumn,
  40. sourceIndex,
  41. originalLine,
  42. originalColumn,
  43. nameIndex,
  44. );
  45. },
  46. (sourceIndex, source, sourceContent) => {
  47. while (potentialSources.length < sourceIndex) {
  48. potentialSources.push(null);
  49. }
  50. potentialSources[sourceIndex] = source;
  51. if (sourceContent !== undefined) {
  52. while (potentialSourcesContent.length < sourceIndex) {
  53. potentialSourcesContent.push(null);
  54. }
  55. potentialSourcesContent[sourceIndex] = sourceContent;
  56. }
  57. },
  58. (nameIndex, name) => {
  59. while (potentialNames.length < nameIndex) {
  60. potentialNames.push(null);
  61. }
  62. potentialNames[nameIndex] = name;
  63. },
  64. );
  65. return mappings.length > 0
  66. ? {
  67. version: 3,
  68. file: "x",
  69. mappings,
  70. // 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
  71. sources: /** @type {string[]} */ (potentialSources),
  72. sourcesContent:
  73. potentialSourcesContent.length > 0
  74. ? /** @type {string[]} */ (potentialSourcesContent)
  75. : undefined,
  76. names: /** @type {string[]} */ (potentialNames),
  77. }
  78. : null;
  79. };
  80. /**
  81. * @param {SourceLikeWithStreamChunks} inputSource input source
  82. * @param {Options=} options options
  83. * @returns {SourceAndMap} map
  84. */
  85. module.exports.getSourceAndMap = (inputSource, options) => {
  86. let code = "";
  87. let mappings = "";
  88. /** @type {(string | null)[]} */
  89. const potentialSources = [];
  90. /** @type {(string | null)[]} */
  91. const potentialSourcesContent = [];
  92. /** @type {(string | null)[]} */
  93. const potentialNames = [];
  94. const addMapping = createMappingsSerializer(options);
  95. const { source } = inputSource.streamChunks(
  96. { ...options, finalSource: true },
  97. (
  98. chunk,
  99. generatedLine,
  100. generatedColumn,
  101. sourceIndex,
  102. originalLine,
  103. originalColumn,
  104. nameIndex,
  105. ) => {
  106. if (chunk !== undefined) code += chunk;
  107. mappings += addMapping(
  108. generatedLine,
  109. generatedColumn,
  110. sourceIndex,
  111. originalLine,
  112. originalColumn,
  113. nameIndex,
  114. );
  115. },
  116. (sourceIndex, source, sourceContent) => {
  117. while (potentialSources.length < sourceIndex) {
  118. potentialSources.push(null);
  119. }
  120. potentialSources[sourceIndex] = source;
  121. if (sourceContent !== undefined) {
  122. while (potentialSourcesContent.length < sourceIndex) {
  123. potentialSourcesContent.push(null);
  124. }
  125. potentialSourcesContent[sourceIndex] = sourceContent;
  126. }
  127. },
  128. (nameIndex, name) => {
  129. while (potentialNames.length < nameIndex) {
  130. potentialNames.push(null);
  131. }
  132. potentialNames[nameIndex] = name;
  133. },
  134. );
  135. return {
  136. source: source !== undefined ? source : code,
  137. map:
  138. mappings.length > 0
  139. ? {
  140. version: 3,
  141. file: "x",
  142. mappings,
  143. // 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
  144. sources: /** @type {string[]} */ (potentialSources),
  145. sourcesContent:
  146. potentialSourcesContent.length > 0
  147. ? /** @type {string[]} */ (potentialSourcesContent)
  148. : undefined,
  149. names: /** @type {string[]} */ (potentialNames),
  150. }
  151. : null,
  152. };
  153. };