DescriptionFilePlugin.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const DescriptionFileUtils = require("./DescriptionFileUtils");
  7. /** @typedef {import("./Resolver")} Resolver */
  8. /** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
  9. /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
  10. const BACKSLASH_G = /\\/g;
  11. module.exports = class DescriptionFilePlugin {
  12. /**
  13. * @param {string | ResolveStepHook} source source
  14. * @param {string[]} filenames filenames
  15. * @param {boolean} pathIsFile pathIsFile
  16. * @param {string | ResolveStepHook} target target
  17. */
  18. constructor(source, filenames, pathIsFile, target) {
  19. this.source = source;
  20. this.filenames = filenames;
  21. this.pathIsFile = pathIsFile;
  22. this.target = target;
  23. }
  24. /**
  25. * @param {Resolver} resolver the resolver
  26. * @returns {void}
  27. */
  28. apply(resolver) {
  29. const target = resolver.ensureHook(this.target);
  30. resolver
  31. .getHook(this.source)
  32. .tapAsync(
  33. "DescriptionFilePlugin",
  34. (request, resolveContext, callback) => {
  35. const { path } = request;
  36. if (!path) return callback();
  37. const directory = this.pathIsFile
  38. ? DescriptionFileUtils.cdUp(path)
  39. : path;
  40. if (!directory) return callback();
  41. DescriptionFileUtils.loadDescriptionFile(
  42. resolver,
  43. directory,
  44. this.filenames,
  45. request.descriptionFilePath
  46. ? {
  47. path: request.descriptionFilePath,
  48. content: request.descriptionFileData,
  49. directory:
  50. /** @type {string} */
  51. (request.descriptionFileRoot),
  52. }
  53. : undefined,
  54. resolveContext,
  55. (err, result) => {
  56. if (err) return callback(err);
  57. if (!result) {
  58. if (resolveContext.log) {
  59. resolveContext.log(
  60. `No description file found in ${directory} or above`,
  61. );
  62. }
  63. return callback();
  64. }
  65. const rawRelative = path.slice(result.directory.length);
  66. const relativePath = `.${
  67. rawRelative.includes("\\")
  68. ? rawRelative.replace(BACKSLASH_G, "/")
  69. : rawRelative
  70. }`;
  71. /** @type {ResolveRequest} */
  72. const obj = {
  73. ...request,
  74. descriptionFilePath: result.path,
  75. descriptionFileData: result.content,
  76. descriptionFileRoot: result.directory,
  77. relativePath,
  78. };
  79. resolver.doResolve(
  80. target,
  81. obj,
  82. `using description file: ${result.path} (relative path: ${relativePath})`,
  83. resolveContext,
  84. (err, result) => {
  85. if (err) return callback(err);
  86. // Don't allow other processing
  87. if (result === undefined) return callback(null, null);
  88. callback(null, result);
  89. },
  90. );
  91. },
  92. );
  93. },
  94. );
  95. }
  96. };