ModuleMap.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _constants = _interopRequireDefault(require('./constants'));
  7. var fastPath = _interopRequireWildcard(require('./lib/fast_path'));
  8. function _getRequireWildcardCache(nodeInterop) {
  9. if (typeof WeakMap !== 'function') return null;
  10. var cacheBabelInterop = new WeakMap();
  11. var cacheNodeInterop = new WeakMap();
  12. return (_getRequireWildcardCache = function (nodeInterop) {
  13. return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
  14. })(nodeInterop);
  15. }
  16. function _interopRequireWildcard(obj, nodeInterop) {
  17. if (!nodeInterop && obj && obj.__esModule) {
  18. return obj;
  19. }
  20. if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
  21. return {default: obj};
  22. }
  23. var cache = _getRequireWildcardCache(nodeInterop);
  24. if (cache && cache.has(obj)) {
  25. return cache.get(obj);
  26. }
  27. var newObj = {};
  28. var hasPropertyDescriptor =
  29. Object.defineProperty && Object.getOwnPropertyDescriptor;
  30. for (var key in obj) {
  31. if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) {
  32. var desc = hasPropertyDescriptor
  33. ? Object.getOwnPropertyDescriptor(obj, key)
  34. : null;
  35. if (desc && (desc.get || desc.set)) {
  36. Object.defineProperty(newObj, key, desc);
  37. } else {
  38. newObj[key] = obj[key];
  39. }
  40. }
  41. }
  42. newObj.default = obj;
  43. if (cache) {
  44. cache.set(obj, newObj);
  45. }
  46. return newObj;
  47. }
  48. function _interopRequireDefault(obj) {
  49. return obj && obj.__esModule ? obj : {default: obj};
  50. }
  51. /**
  52. * Copyright (c) Meta Platforms, Inc. and affiliates.
  53. *
  54. * This source code is licensed under the MIT license found in the
  55. * LICENSE file in the root directory of this source tree.
  56. */
  57. const EMPTY_OBJ = {};
  58. const EMPTY_MAP = new Map();
  59. class ModuleMap {
  60. static DuplicateHasteCandidatesError;
  61. _raw;
  62. json;
  63. static mapToArrayRecursive(map) {
  64. let arr = Array.from(map);
  65. if (arr[0] && arr[0][1] instanceof Map) {
  66. arr = arr.map(el => [el[0], this.mapToArrayRecursive(el[1])]);
  67. }
  68. return arr;
  69. }
  70. static mapFromArrayRecursive(arr) {
  71. if (arr[0] && Array.isArray(arr[1])) {
  72. arr = arr.map(el => [el[0], this.mapFromArrayRecursive(el[1])]);
  73. }
  74. return new Map(arr);
  75. }
  76. constructor(raw) {
  77. this._raw = raw;
  78. }
  79. getModule(name, platform, supportsNativePlatform, type) {
  80. if (type == null) {
  81. type = _constants.default.MODULE;
  82. }
  83. const module = this._getModuleMetadata(
  84. name,
  85. platform,
  86. !!supportsNativePlatform
  87. );
  88. if (module && module[_constants.default.TYPE] === type) {
  89. const modulePath = module[_constants.default.PATH];
  90. return modulePath && fastPath.resolve(this._raw.rootDir, modulePath);
  91. }
  92. return null;
  93. }
  94. getPackage(name, platform, _supportsNativePlatform) {
  95. return this.getModule(name, platform, null, _constants.default.PACKAGE);
  96. }
  97. getMockModule(name) {
  98. const mockPath =
  99. this._raw.mocks.get(name) || this._raw.mocks.get(`${name}/index`);
  100. return mockPath && fastPath.resolve(this._raw.rootDir, mockPath);
  101. }
  102. getRawModuleMap() {
  103. return {
  104. duplicates: this._raw.duplicates,
  105. map: this._raw.map,
  106. mocks: this._raw.mocks,
  107. rootDir: this._raw.rootDir
  108. };
  109. }
  110. toJSON() {
  111. if (!this.json) {
  112. this.json = {
  113. duplicates: ModuleMap.mapToArrayRecursive(this._raw.duplicates),
  114. map: Array.from(this._raw.map),
  115. mocks: Array.from(this._raw.mocks),
  116. rootDir: this._raw.rootDir
  117. };
  118. }
  119. return this.json;
  120. }
  121. static fromJSON(serializableModuleMap) {
  122. return new ModuleMap({
  123. duplicates: ModuleMap.mapFromArrayRecursive(
  124. serializableModuleMap.duplicates
  125. ),
  126. map: new Map(serializableModuleMap.map),
  127. mocks: new Map(serializableModuleMap.mocks),
  128. rootDir: serializableModuleMap.rootDir
  129. });
  130. }
  131. /**
  132. * When looking up a module's data, we walk through each eligible platform for
  133. * the query. For each platform, we want to check if there are known
  134. * duplicates for that name+platform pair. The duplication logic normally
  135. * removes elements from the `map` object, but we want to check upfront to be
  136. * extra sure. If metadata exists both in the `duplicates` object and the
  137. * `map`, this would be a bug.
  138. */
  139. _getModuleMetadata(name, platform, supportsNativePlatform) {
  140. const map = this._raw.map.get(name) || EMPTY_OBJ;
  141. const dupMap = this._raw.duplicates.get(name) || EMPTY_MAP;
  142. if (platform != null) {
  143. this._assertNoDuplicates(
  144. name,
  145. platform,
  146. supportsNativePlatform,
  147. dupMap.get(platform)
  148. );
  149. if (map[platform] != null) {
  150. return map[platform];
  151. }
  152. }
  153. if (supportsNativePlatform) {
  154. this._assertNoDuplicates(
  155. name,
  156. _constants.default.NATIVE_PLATFORM,
  157. supportsNativePlatform,
  158. dupMap.get(_constants.default.NATIVE_PLATFORM)
  159. );
  160. if (map[_constants.default.NATIVE_PLATFORM]) {
  161. return map[_constants.default.NATIVE_PLATFORM];
  162. }
  163. }
  164. this._assertNoDuplicates(
  165. name,
  166. _constants.default.GENERIC_PLATFORM,
  167. supportsNativePlatform,
  168. dupMap.get(_constants.default.GENERIC_PLATFORM)
  169. );
  170. if (map[_constants.default.GENERIC_PLATFORM]) {
  171. return map[_constants.default.GENERIC_PLATFORM];
  172. }
  173. return null;
  174. }
  175. _assertNoDuplicates(name, platform, supportsNativePlatform, relativePathSet) {
  176. if (relativePathSet == null) {
  177. return;
  178. }
  179. // Force flow refinement
  180. const previousSet = relativePathSet;
  181. const duplicates = new Map();
  182. for (const [relativePath, type] of previousSet) {
  183. const duplicatePath = fastPath.resolve(this._raw.rootDir, relativePath);
  184. duplicates.set(duplicatePath, type);
  185. }
  186. throw new DuplicateHasteCandidatesError(
  187. name,
  188. platform,
  189. supportsNativePlatform,
  190. duplicates
  191. );
  192. }
  193. static create(rootDir) {
  194. return new ModuleMap({
  195. duplicates: new Map(),
  196. map: new Map(),
  197. mocks: new Map(),
  198. rootDir
  199. });
  200. }
  201. }
  202. exports.default = ModuleMap;
  203. class DuplicateHasteCandidatesError extends Error {
  204. hasteName;
  205. platform;
  206. supportsNativePlatform;
  207. duplicatesSet;
  208. constructor(name, platform, supportsNativePlatform, duplicatesSet) {
  209. const platformMessage = getPlatformMessage(platform);
  210. super(
  211. `The name \`${name}\` was looked up in the Haste module map. It ` +
  212. 'cannot be resolved, because there exists several different ' +
  213. 'files, or packages, that provide a module for ' +
  214. `that particular name and platform. ${platformMessage} You must ` +
  215. `delete or exclude files until there remains only one of these:\n\n${Array.from(
  216. duplicatesSet
  217. )
  218. .map(
  219. ([dupFilePath, dupFileType]) =>
  220. ` * \`${dupFilePath}\` (${getTypeMessage(dupFileType)})\n`
  221. )
  222. .sort()
  223. .join('')}`
  224. );
  225. this.hasteName = name;
  226. this.platform = platform;
  227. this.supportsNativePlatform = supportsNativePlatform;
  228. this.duplicatesSet = duplicatesSet;
  229. }
  230. }
  231. function getPlatformMessage(platform) {
  232. if (platform === _constants.default.GENERIC_PLATFORM) {
  233. return 'The platform is generic (no extension).';
  234. }
  235. return `The platform extension is \`${platform}\`.`;
  236. }
  237. function getTypeMessage(type) {
  238. switch (type) {
  239. case _constants.default.MODULE:
  240. return 'module';
  241. case _constants.default.PACKAGE:
  242. return 'package';
  243. }
  244. return 'unknown';
  245. }
  246. ModuleMap.DuplicateHasteCandidatesError = DuplicateHasteCandidatesError;