ParsePlugin.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /** @typedef {import("./Resolver")} Resolver */
  7. /** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
  8. /** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
  9. module.exports = class ParsePlugin {
  10. /**
  11. * @param {string | ResolveStepHook} source source
  12. * @param {Partial<ResolveRequest>} requestOptions request options
  13. * @param {string | ResolveStepHook} target target
  14. */
  15. constructor(source, requestOptions, target) {
  16. this.source = source;
  17. this.requestOptions = requestOptions;
  18. this.target = target;
  19. }
  20. /**
  21. * @param {Resolver} resolver the resolver
  22. * @returns {void}
  23. */
  24. apply(resolver) {
  25. const target = resolver.ensureHook(this.target);
  26. resolver
  27. .getHook(this.source)
  28. .tapAsync("ParsePlugin", (request, resolveContext, callback) => {
  29. const parsed = resolver.parse(/** @type {string} */ (request.request));
  30. const obj = { ...request, ...parsed, ...this.requestOptions };
  31. if (request.query && !parsed.query) {
  32. obj.query = request.query;
  33. }
  34. if (request.fragment && !parsed.fragment) {
  35. obj.fragment = request.fragment;
  36. }
  37. if (parsed && resolveContext.log) {
  38. if (parsed.module) resolveContext.log("Parsed request is a module");
  39. if (parsed.directory)
  40. resolveContext.log("Parsed request is a directory");
  41. }
  42. // There is an edge-case where a request with # can be a path or a fragment -> try both
  43. if (obj.request && !obj.query && obj.fragment) {
  44. const directory = obj.fragment.endsWith("/");
  45. const alternative = {
  46. ...obj,
  47. directory,
  48. request:
  49. obj.request +
  50. (obj.directory ? "/" : "") +
  51. (directory ? obj.fragment.slice(0, -1) : obj.fragment),
  52. fragment: ""
  53. };
  54. resolver.doResolve(
  55. target,
  56. alternative,
  57. null,
  58. resolveContext,
  59. (err, result) => {
  60. if (err) return callback(err);
  61. if (result) return callback(null, result);
  62. resolver.doResolve(target, obj, null, resolveContext, callback);
  63. }
  64. );
  65. return;
  66. }
  67. resolver.doResolve(target, obj, null, resolveContext, callback);
  68. });
  69. }
  70. };