source: trip-planner-front/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Ivan Kopeykin @vankop
4*/
5
6"use strict";
7
8const path = require("path");
9const DescriptionFileUtils = require("./DescriptionFileUtils");
10const forEachBail = require("./forEachBail");
11const { processExportsField } = require("./util/entrypoints");
12const { parseIdentifier } = require("./util/identifier");
13const { checkExportsFieldTarget } = require("./util/path");
14
15/** @typedef {import("./Resolver")} Resolver */
16/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
17/** @typedef {import("./util/entrypoints").ExportsField} ExportsField */
18/** @typedef {import("./util/entrypoints").FieldProcessor} FieldProcessor */
19
20module.exports = class ExportsFieldPlugin {
21 /**
22 * @param {string | ResolveStepHook} source source
23 * @param {Set<string>} conditionNames condition names
24 * @param {string | string[]} fieldNamePath name path
25 * @param {string | ResolveStepHook} target target
26 */
27 constructor(source, conditionNames, fieldNamePath, target) {
28 this.source = source;
29 this.target = target;
30 this.conditionNames = conditionNames;
31 this.fieldName = fieldNamePath;
32 /** @type {WeakMap<any, FieldProcessor>} */
33 this.fieldProcessorCache = new WeakMap();
34 }
35
36 /**
37 * @param {Resolver} resolver the resolver
38 * @returns {void}
39 */
40 apply(resolver) {
41 const target = resolver.ensureHook(this.target);
42 resolver
43 .getHook(this.source)
44 .tapAsync("ExportsFieldPlugin", (request, resolveContext, callback) => {
45 // When there is no description file, abort
46 if (!request.descriptionFilePath) return callback();
47 if (
48 // When the description file is inherited from parent, abort
49 // (There is no description file inside of this package)
50 request.relativePath !== "." ||
51 request.request === undefined
52 )
53 return callback();
54
55 const remainingRequest =
56 request.query || request.fragment
57 ? (request.request === "." ? "./" : request.request) +
58 request.query +
59 request.fragment
60 : request.request;
61 /** @type {ExportsField|null} */
62 const exportsField = DescriptionFileUtils.getField(
63 request.descriptionFileData,
64 this.fieldName
65 );
66 if (!exportsField) return callback();
67
68 if (request.directory) {
69 return callback(
70 new Error(
71 `Resolving to directories is not possible with the exports field (request was ${remainingRequest}/)`
72 )
73 );
74 }
75
76 let paths;
77
78 try {
79 // We attach the cache to the description file instead of the exportsField value
80 // because we use a WeakMap and the exportsField could be a string too.
81 // Description file is always an object when exports field can be accessed.
82 let fieldProcessor = this.fieldProcessorCache.get(
83 request.descriptionFileData
84 );
85 if (fieldProcessor === undefined) {
86 fieldProcessor = processExportsField(exportsField);
87 this.fieldProcessorCache.set(
88 request.descriptionFileData,
89 fieldProcessor
90 );
91 }
92 paths = fieldProcessor(remainingRequest, this.conditionNames);
93 } catch (err) {
94 if (resolveContext.log) {
95 resolveContext.log(
96 `Exports field in ${request.descriptionFilePath} can't be processed: ${err}`
97 );
98 }
99 return callback(err);
100 }
101
102 if (paths.length === 0) {
103 return callback(
104 new Error(
105 `Package path ${remainingRequest} is not exported from package ${request.descriptionFileRoot} (see exports field in ${request.descriptionFilePath})`
106 )
107 );
108 }
109
110 forEachBail(
111 paths,
112 (p, callback) => {
113 const parsedIdentifier = parseIdentifier(p);
114
115 if (!parsedIdentifier) return callback();
116
117 const [relativePath, query, fragment] = parsedIdentifier;
118
119 const error = checkExportsFieldTarget(relativePath);
120
121 if (error) {
122 return callback(error);
123 }
124
125 const obj = {
126 ...request,
127 request: undefined,
128 path: path.join(
129 /** @type {string} */ (request.descriptionFileRoot),
130 relativePath
131 ),
132 relativePath,
133 query,
134 fragment
135 };
136
137 resolver.doResolve(
138 target,
139 obj,
140 "using exports field: " + p,
141 resolveContext,
142 callback
143 );
144 },
145 (err, result) => callback(err, result || null)
146 );
147 });
148 }
149};
Note: See TracBrowser for help on using the repository browser.