streamAndGetSourceAndMap.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. const streamChunks = require("./streamChunks");
  8. /** @typedef {import("../Source").RawSourceMap} RawSourceMap */
  9. /** @typedef {import("./streamChunks").GeneratedSourceInfo} GeneratedSourceInfo */
  10. /** @typedef {import("./streamChunks").OnChunk} OnChunk */
  11. /** @typedef {import("./streamChunks").OnName} OnName */
  12. /** @typedef {import("./streamChunks").OnSource} OnSource */
  13. /** @typedef {import("./streamChunks").Options} Options */
  14. /** @typedef {import("./streamChunks").SourceMaybeWithStreamChunksFunction} SourceMaybeWithStreamChunksFunction */
  15. /**
  16. * @param {SourceMaybeWithStreamChunksFunction} inputSource input source
  17. * @param {Options} options options
  18. * @param {OnChunk} onChunk on chunk
  19. * @param {OnSource} onSource on source
  20. * @param {OnName} onName on name
  21. * @returns {{ result: GeneratedSourceInfo, source: string, map: RawSourceMap | null }} result
  22. */
  23. const streamAndGetSourceAndMap = (
  24. inputSource,
  25. options,
  26. onChunk,
  27. onSource,
  28. onName,
  29. ) => {
  30. let code = "";
  31. let mappings = "";
  32. /** @type {(string | null)[]} */
  33. const potentialSources = [];
  34. /** @type {(string | null)[]} */
  35. const potentialSourcesContent = [];
  36. /** @type {(string | null)[]} */
  37. const potentialNames = [];
  38. const addMapping = createMappingsSerializer({ ...options, columns: true });
  39. const finalSource = Boolean(options && options.finalSource);
  40. const { generatedLine, generatedColumn, source } = streamChunks(
  41. inputSource,
  42. options,
  43. (
  44. chunk,
  45. generatedLine,
  46. generatedColumn,
  47. sourceIndex,
  48. originalLine,
  49. originalColumn,
  50. nameIndex,
  51. ) => {
  52. if (chunk !== undefined) code += chunk;
  53. mappings += addMapping(
  54. generatedLine,
  55. generatedColumn,
  56. sourceIndex,
  57. originalLine,
  58. originalColumn,
  59. nameIndex,
  60. );
  61. return onChunk(
  62. finalSource ? undefined : chunk,
  63. generatedLine,
  64. generatedColumn,
  65. sourceIndex,
  66. originalLine,
  67. originalColumn,
  68. nameIndex,
  69. );
  70. },
  71. (sourceIndex, source, sourceContent) => {
  72. while (potentialSources.length < sourceIndex) {
  73. potentialSources.push(null);
  74. }
  75. potentialSources[sourceIndex] = source;
  76. if (sourceContent !== undefined) {
  77. while (potentialSourcesContent.length < sourceIndex) {
  78. potentialSourcesContent.push(null);
  79. }
  80. potentialSourcesContent[sourceIndex] = sourceContent;
  81. }
  82. return onSource(sourceIndex, source, sourceContent);
  83. },
  84. (nameIndex, name) => {
  85. while (potentialNames.length < nameIndex) {
  86. potentialNames.push(null);
  87. }
  88. potentialNames[nameIndex] = name;
  89. return onName(nameIndex, name);
  90. },
  91. );
  92. const resultSource = source !== undefined ? source : code;
  93. return {
  94. result: {
  95. generatedLine,
  96. generatedColumn,
  97. source: finalSource ? resultSource : undefined,
  98. },
  99. source: resultSource,
  100. map:
  101. mappings.length > 0
  102. ? {
  103. version: 3,
  104. file: "x",
  105. mappings,
  106. // 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
  107. sources: /** @type {string[]} */ (potentialSources),
  108. sourcesContent:
  109. potentialSourcesContent.length > 0
  110. ? /** @type {string[]} */ (potentialSourcesContent)
  111. : undefined,
  112. names: /** @type {string[]} */ (potentialNames),
  113. }
  114. : null,
  115. };
  116. };
  117. module.exports = streamAndGetSourceAndMap;