source: trip-planner-front/node_modules/enhanced-resolve/lib/ImportsFieldPlugin.js@ 6a80231

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

initial commit

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[6a3a178]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 { processImportsField } = require("./util/entrypoints");
12const { parseIdentifier } = require("./util/identifier");
13
14/** @typedef {import("./Resolver")} Resolver */
15/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
16/** @typedef {import("./util/entrypoints").FieldProcessor} FieldProcessor */
17/** @typedef {import("./util/entrypoints").ImportsField} ImportsField */
18
19const dotCode = ".".charCodeAt(0);
20
21module.exports = class ImportsFieldPlugin {
22 /**
23 * @param {string | ResolveStepHook} source source
24 * @param {Set<string>} conditionNames condition names
25 * @param {string | string[]} fieldNamePath name path
26 * @param {string | ResolveStepHook} targetFile target file
27 * @param {string | ResolveStepHook} targetPackage target package
28 */
29 constructor(
30 source,
31 conditionNames,
32 fieldNamePath,
33 targetFile,
34 targetPackage
35 ) {
36 this.source = source;
37 this.targetFile = targetFile;
38 this.targetPackage = targetPackage;
39 this.conditionNames = conditionNames;
40 this.fieldName = fieldNamePath;
41 /** @type {WeakMap<any, FieldProcessor>} */
42 this.fieldProcessorCache = new WeakMap();
43 }
44
45 /**
46 * @param {Resolver} resolver the resolver
47 * @returns {void}
48 */
49 apply(resolver) {
50 const targetFile = resolver.ensureHook(this.targetFile);
51 const targetPackage = resolver.ensureHook(this.targetPackage);
52
53 resolver
54 .getHook(this.source)
55 .tapAsync("ImportsFieldPlugin", (request, resolveContext, callback) => {
56 // When there is no description file, abort
57 if (!request.descriptionFilePath || request.request === undefined) {
58 return callback();
59 }
60
61 const remainingRequest =
62 request.request + request.query + request.fragment;
63 /** @type {ImportsField|null} */
64 const importsField = DescriptionFileUtils.getField(
65 request.descriptionFileData,
66 this.fieldName
67 );
68 if (!importsField) return callback();
69
70 if (request.directory) {
71 return callback(
72 new Error(
73 `Resolving to directories is not possible with the imports field (request was ${remainingRequest}/)`
74 )
75 );
76 }
77
78 let paths;
79
80 try {
81 // We attach the cache to the description file instead of the importsField value
82 // because we use a WeakMap and the importsField could be a string too.
83 // Description file is always an object when exports field can be accessed.
84 let fieldProcessor = this.fieldProcessorCache.get(
85 request.descriptionFileData
86 );
87 if (fieldProcessor === undefined) {
88 fieldProcessor = processImportsField(importsField);
89 this.fieldProcessorCache.set(
90 request.descriptionFileData,
91 fieldProcessor
92 );
93 }
94 paths = fieldProcessor(remainingRequest, this.conditionNames);
95 } catch (err) {
96 if (resolveContext.log) {
97 resolveContext.log(
98 `Imports field in ${request.descriptionFilePath} can't be processed: ${err}`
99 );
100 }
101 return callback(err);
102 }
103
104 if (paths.length === 0) {
105 return callback(
106 new Error(
107 `Package import ${remainingRequest} is not imported from package ${request.descriptionFileRoot} (see imports field in ${request.descriptionFilePath})`
108 )
109 );
110 }
111
112 forEachBail(
113 paths,
114 (p, callback) => {
115 const parsedIdentifier = parseIdentifier(p);
116
117 if (!parsedIdentifier) return callback();
118
119 const [path_, query, fragment] = parsedIdentifier;
120
121 switch (path_.charCodeAt(0)) {
122 // should be relative
123 case dotCode: {
124 const obj = {
125 ...request,
126 request: undefined,
127 path: path.join(
128 /** @type {string} */ (request.descriptionFileRoot),
129 path_
130 ),
131 relativePath: path_,
132 query,
133 fragment
134 };
135
136 resolver.doResolve(
137 targetFile,
138 obj,
139 "using imports field: " + p,
140 resolveContext,
141 callback
142 );
143 break;
144 }
145
146 // package resolving
147 default: {
148 const obj = {
149 ...request,
150 request: path_,
151 relativePath: path_,
152 fullySpecified: true,
153 query,
154 fragment
155 };
156
157 resolver.doResolve(
158 targetPackage,
159 obj,
160 "using imports field: " + p,
161 resolveContext,
162 callback
163 );
164 }
165 }
166 },
167 (err, result) => callback(err, result || null)
168 );
169 });
170 }
171};
Note: See TracBrowser for help on using the repository browser.