source: imaps-frontend/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 6.0 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 DescriptionFileUtils = require("./DescriptionFileUtils");
9const forEachBail = require("./forEachBail");
10const { processExportsField } = require("./util/entrypoints");
11const { parseIdentifier } = require("./util/identifier");
12const {
13 invalidSegmentRegEx,
14 deprecatedInvalidSegmentRegEx
15} = require("./util/path");
16
17/** @typedef {import("./Resolver")} Resolver */
18/** @typedef {import("./Resolver").JsonObject} JsonObject */
19/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
20/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
21/** @typedef {import("./util/entrypoints").ExportsField} ExportsField */
22/** @typedef {import("./util/entrypoints").FieldProcessor} FieldProcessor */
23
24module.exports = class ExportsFieldPlugin {
25 /**
26 * @param {string | ResolveStepHook} source source
27 * @param {Set<string>} conditionNames condition names
28 * @param {string | string[]} fieldNamePath name path
29 * @param {string | ResolveStepHook} target target
30 */
31 constructor(source, conditionNames, fieldNamePath, target) {
32 this.source = source;
33 this.target = target;
34 this.conditionNames = conditionNames;
35 this.fieldName = fieldNamePath;
36 /** @type {WeakMap<JsonObject, FieldProcessor>} */
37 this.fieldProcessorCache = new WeakMap();
38 }
39
40 /**
41 * @param {Resolver} resolver the resolver
42 * @returns {void}
43 */
44 apply(resolver) {
45 const target = resolver.ensureHook(this.target);
46 resolver
47 .getHook(this.source)
48 .tapAsync("ExportsFieldPlugin", (request, resolveContext, callback) => {
49 // When there is no description file, abort
50 if (!request.descriptionFilePath) return callback();
51 if (
52 // When the description file is inherited from parent, abort
53 // (There is no description file inside of this package)
54 request.relativePath !== "." ||
55 request.request === undefined
56 )
57 return callback();
58
59 const remainingRequest =
60 request.query || request.fragment
61 ? (request.request === "." ? "./" : request.request) +
62 request.query +
63 request.fragment
64 : request.request;
65 const exportsField =
66 /** @type {ExportsField|null|undefined} */
67 (
68 DescriptionFileUtils.getField(
69 /** @type {JsonObject} */ (request.descriptionFileData),
70 this.fieldName
71 )
72 );
73 if (!exportsField) return callback();
74
75 if (request.directory) {
76 return callback(
77 new Error(
78 `Resolving to directories is not possible with the exports field (request was ${remainingRequest}/)`
79 )
80 );
81 }
82
83 /** @type {string[]} */
84 let paths;
85 /** @type {string | null} */
86 let usedField;
87
88 try {
89 // We attach the cache to the description file instead of the exportsField value
90 // because we use a WeakMap and the exportsField could be a string too.
91 // Description file is always an object when exports field can be accessed.
92 let fieldProcessor = this.fieldProcessorCache.get(
93 /** @type {JsonObject} */ (request.descriptionFileData)
94 );
95 if (fieldProcessor === undefined) {
96 fieldProcessor = processExportsField(exportsField);
97 this.fieldProcessorCache.set(
98 /** @type {JsonObject} */ (request.descriptionFileData),
99 fieldProcessor
100 );
101 }
102 [paths, usedField] = fieldProcessor(
103 remainingRequest,
104 this.conditionNames
105 );
106 } catch (/** @type {unknown} */ err) {
107 if (resolveContext.log) {
108 resolveContext.log(
109 `Exports field in ${request.descriptionFilePath} can't be processed: ${err}`
110 );
111 }
112 return callback(/** @type {Error} */ (err));
113 }
114
115 if (paths.length === 0) {
116 return callback(
117 new Error(
118 `Package path ${remainingRequest} is not exported from package ${request.descriptionFileRoot} (see exports field in ${request.descriptionFilePath})`
119 )
120 );
121 }
122
123 forEachBail(
124 paths,
125 /**
126 * @param {string} p path
127 * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
128 * @param {number} i index
129 * @returns {void}
130 */
131 (p, callback, i) => {
132 const parsedIdentifier = parseIdentifier(p);
133
134 if (!parsedIdentifier) return callback();
135
136 const [relativePath, query, fragment] = parsedIdentifier;
137
138 if (relativePath.length === 0 || !relativePath.startsWith("./")) {
139 if (paths.length === i) {
140 return callback(
141 new Error(
142 `Invalid "exports" target "${p}" defined for "${usedField}" in the package config ${request.descriptionFilePath}, targets must start with "./"`
143 )
144 );
145 }
146
147 return callback();
148 }
149
150 if (
151 invalidSegmentRegEx.exec(relativePath.slice(2)) !== null &&
152 deprecatedInvalidSegmentRegEx.test(relativePath.slice(2)) !== null
153 ) {
154 if (paths.length === i) {
155 return callback(
156 new Error(
157 `Invalid "exports" target "${p}" defined for "${usedField}" in the package config ${request.descriptionFilePath}, targets must start with "./"`
158 )
159 );
160 }
161
162 return callback();
163 }
164
165 /** @type {ResolveRequest} */
166 const obj = {
167 ...request,
168 request: undefined,
169 path: resolver.join(
170 /** @type {string} */ (request.descriptionFileRoot),
171 relativePath
172 ),
173 relativePath,
174 query,
175 fragment
176 };
177
178 resolver.doResolve(
179 target,
180 obj,
181 "using exports field: " + p,
182 resolveContext,
183 (err, result) => {
184 if (err) return callback(err);
185 // Don't allow to continue - https://github.com/webpack/enhanced-resolve/issues/400
186 if (result === undefined) return callback(null, null);
187 callback(null, result);
188 }
189 );
190 },
191 /**
192 * @param {null|Error} [err] error
193 * @param {null|ResolveRequest} [result] result
194 * @returns {void}
195 */
196 (err, result) => callback(err, result || null)
197 );
198 });
199 }
200};
Note: See TracBrowser for help on using the repository browser.