@jsenv/core 40.8.1 → 40.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,11 +21,13 @@ export const createNodeEsmResolver = ({
21
21
  runtimeCompat,
22
22
  rootDirectoryUrl,
23
23
  packageConditions = {},
24
+ packageConditionsConfig,
24
25
  preservesSymlink,
25
26
  }) => {
26
27
  const buildPackageConditions = createBuildPackageConditions(
27
28
  packageConditions,
28
29
  {
30
+ packageConditionsConfig,
29
31
  rootDirectoryUrl,
30
32
  runtimeCompat,
31
33
  },
@@ -57,26 +59,43 @@ export const createNodeEsmResolver = ({
57
59
  const webResolutionFallback =
58
60
  ownerUrlInfo.type !== "js_module" ||
59
61
  reference.type === "sourcemap_comment";
62
+
63
+ const resolveNodeEsmFallbackOnWeb = createResolverWithFallbackOnError(
64
+ applyNodeEsmResolution,
65
+ ({ specifier, parentUrl }) => {
66
+ const url = new URL(specifier, parentUrl).href;
67
+ return { url };
68
+ },
69
+ );
70
+ const DELEGATE_TO_WEB_RESOLUTION_PLUGIN = {};
71
+ const resolveNodeEsmFallbackNullToDelegateToWebPlugin =
72
+ createResolverWithFallbackOnError(
73
+ applyNodeEsmResolution,
74
+
75
+ () => DELEGATE_TO_WEB_RESOLUTION_PLUGIN,
76
+ );
77
+
60
78
  const conditions = buildPackageConditions(specifier, parentUrl, {
61
79
  webResolutionFallback,
80
+ resolver: webResolutionFallback
81
+ ? resolveNodeEsmFallbackOnWeb
82
+ : applyNodeEsmResolution,
62
83
  });
63
- let resolution;
64
- const nodeEsmResolutionParams = {
84
+ const resolver = webResolutionFallback
85
+ ? resolveNodeEsmFallbackNullToDelegateToWebPlugin
86
+ : applyNodeEsmResolution;
87
+
88
+ const result = resolver({
65
89
  conditions,
66
90
  parentUrl,
67
91
  specifier,
68
92
  preservesSymlink,
69
- };
70
- if (webResolutionFallback) {
71
- try {
72
- resolution = applyNodeEsmResolution(nodeEsmResolutionParams);
73
- } catch {
74
- return null; // delegate to web_resolution plugin
75
- }
76
- } else {
77
- resolution = applyNodeEsmResolution(nodeEsmResolutionParams);
93
+ });
94
+ if (result === DELEGATE_TO_WEB_RESOLUTION_PLUGIN) {
95
+ return null;
78
96
  }
79
- const { url, type, isMain, packageDirectoryUrl } = resolution;
97
+
98
+ const { url, type, isMain, packageDirectoryUrl } = result;
80
99
  // try to give a more meaningful filename after build
81
100
  if (isMain && packageDirectoryUrl) {
82
101
  const basename = urlToBasename(url);
@@ -140,147 +159,232 @@ export const createNodeEsmResolver = ({
140
159
 
141
160
  const createBuildPackageConditions = (
142
161
  packageConditions,
143
- { rootDirectoryUrl, runtimeCompat },
162
+ { packageConditionsConfig, rootDirectoryUrl, runtimeCompat },
144
163
  ) => {
145
- const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node");
146
- // https://nodejs.org/api/esm.html#resolver-algorithm-specification
147
- const processArgConditions = readCustomConditionsFromProcessArgs();
148
- const devResolver = (specifier, importer, { webResolutionFallback }) => {
149
- if (isBareSpecifier(specifier)) {
150
- let url;
151
- if (webResolutionFallback) {
152
- try {
153
- const resolution = applyNodeEsmResolution({
154
- specifier,
155
- parentUrl: importer,
164
+ let resolveConditionsFromSpecifier = () => null;
165
+ let resolveConditionsFromContext = () => [];
166
+ from_specifier: {
167
+ if (!packageConditionsConfig) {
168
+ break from_specifier;
169
+ }
170
+ const keys = Object.keys(packageConditionsConfig);
171
+ if (keys.length === 0) {
172
+ break from_specifier;
173
+ }
174
+
175
+ const associationsRaw = {};
176
+ for (const key of keys) {
177
+ const associatedValue = packageConditionsConfig[key];
178
+
179
+ if (!isBareSpecifier(key)) {
180
+ const url = new URL(key, rootDirectoryUrl);
181
+ associationsRaw[url] = associatedValue;
182
+ continue;
183
+ }
184
+ try {
185
+ if (key.endsWith("/")) {
186
+ const { packageDirectoryUrl } = applyNodeEsmResolution({
187
+ specifier: key.slice(0, -1), // avoid package path not exported
188
+ parentUrl: rootDirectoryUrl,
156
189
  });
157
- url = resolution.url;
158
- } catch {
159
- url = new URL(specifier, importer).href;
190
+ const url = packageDirectoryUrl;
191
+ associationsRaw[url] = associatedValue;
192
+ continue;
160
193
  }
194
+ const { url } = applyNodeEsmResolution({
195
+ specifier: key,
196
+ parentUrl: rootDirectoryUrl,
197
+ });
198
+ associationsRaw[url] = associatedValue;
199
+ } catch {
200
+ const url = new URL(key, rootDirectoryUrl);
201
+ associationsRaw[url] = associatedValue;
202
+ }
203
+ }
204
+ const associations = URL_META.resolveAssociations(
205
+ {
206
+ conditions: associationsRaw,
207
+ },
208
+ rootDirectoryUrl,
209
+ );
210
+ resolveConditionsFromSpecifier = (specifier, importer, { resolver }) => {
211
+ let associatedValue;
212
+ if (isBareSpecifier(specifier)) {
213
+ const { url } = resolver({
214
+ specifier,
215
+ parentUrl: importer,
216
+ });
217
+ associatedValue = URL_META.applyAssociations({ url, associations });
161
218
  } else {
162
- const resolution = applyNodeEsmResolution({
219
+ associatedValue = URL_META.applyAssociations({
220
+ url: importer,
221
+ associations,
222
+ });
223
+ }
224
+ if (!associatedValue) {
225
+ return undefined;
226
+ }
227
+ if (associatedValue.conditions) {
228
+ return associatedValue.conditions;
229
+ }
230
+ return undefined;
231
+ };
232
+ }
233
+ from_context: {
234
+ const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node");
235
+ // https://nodejs.org/api/esm.html#resolver-algorithm-specification
236
+ const devResolver = (specifier, importer, { resolver }) => {
237
+ if (isBareSpecifier(specifier)) {
238
+ const { url } = resolver({
163
239
  specifier,
164
240
  parentUrl: importer,
165
241
  });
166
- url = resolution.url;
242
+ return !url.includes("/node_modules/");
167
243
  }
168
- return !url.includes("/node_modules/");
169
- }
170
- return !importer.includes("/node_modules/");
171
- };
244
+ return !importer.includes("/node_modules/");
245
+ };
172
246
 
173
- const conditionDefaultResolvers = {
174
- "dev:*": devResolver,
175
- "development": devResolver,
176
- "node": nodeRuntimeEnabled,
177
- "browser": !nodeRuntimeEnabled,
178
- "import": true,
179
- };
180
- const conditionResolvers = {
181
- ...conditionDefaultResolvers,
182
- };
247
+ const conditionDefaultResolvers = {
248
+ "dev:*": devResolver,
249
+ "development": devResolver,
250
+ "node": nodeRuntimeEnabled,
251
+ "browser": !nodeRuntimeEnabled,
252
+ "import": true,
253
+ };
254
+ const conditionResolvers = {
255
+ ...conditionDefaultResolvers,
256
+ };
183
257
 
184
- let wildcardToRemoveSet = new Set();
185
- const addCustomResolver = (condition, customResolver) => {
186
- for (const conditionCandidate of Object.keys(conditionDefaultResolvers)) {
187
- if (conditionCandidate.includes("*")) {
188
- const conditionRegex = new RegExp(
189
- `^${conditionCandidate.replace(/\*/g, "(.*)")}$`,
190
- );
191
- if (conditionRegex.test(condition)) {
192
- const existingResolver =
193
- conditionDefaultResolvers[conditionCandidate];
194
- wildcardToRemoveSet.add(conditionCandidate);
195
- conditionResolvers[condition] = combineTwoPackageConditionResolvers(
196
- existingResolver,
197
- customResolver,
258
+ let wildcardToRemoveSet = new Set();
259
+ const addCustomResolver = (condition, customResolver) => {
260
+ for (const conditionCandidate of Object.keys(conditionDefaultResolvers)) {
261
+ if (conditionCandidate.includes("*")) {
262
+ const conditionRegex = new RegExp(
263
+ `^${conditionCandidate.replace(/\*/g, "(.*)")}$`,
198
264
  );
199
- return;
265
+ if (conditionRegex.test(condition)) {
266
+ const existingResolver =
267
+ conditionDefaultResolvers[conditionCandidate];
268
+ wildcardToRemoveSet.add(conditionCandidate);
269
+ conditionResolvers[condition] = combineTwoPackageConditionResolvers(
270
+ existingResolver,
271
+ customResolver,
272
+ );
273
+ return;
274
+ }
200
275
  }
201
276
  }
277
+ const existingResolver = conditionDefaultResolvers[condition];
278
+ if (existingResolver) {
279
+ conditionResolvers[condition] = combineTwoPackageConditionResolvers(
280
+ existingResolver,
281
+ customResolver,
282
+ );
283
+ return;
284
+ }
285
+ conditionResolvers[condition] = customResolver;
286
+ };
287
+ custom_resolvers_from_process_args: {
288
+ const processArgConditions = readCustomConditionsFromProcessArgs();
289
+ for (const processArgCondition of processArgConditions) {
290
+ addCustomResolver(processArgCondition, true);
291
+ }
202
292
  }
203
- const existingResolver = conditionDefaultResolvers[condition];
204
- if (existingResolver) {
205
- conditionResolvers[condition] = combineTwoPackageConditionResolvers(
206
- existingResolver,
207
- customResolver,
208
- );
209
- return;
210
- }
211
- conditionResolvers[condition] = customResolver;
212
- };
213
-
214
- for (const processArgCondition of processArgConditions) {
215
- addCustomResolver(processArgCondition, true);
216
- }
217
- for (const customCondition of Object.keys(packageConditions)) {
218
- const value = packageConditions[customCondition];
219
- let customResolver;
220
- if (typeof value === "object") {
221
- const associations = URL_META.resolveAssociations(
222
- { applies: value },
223
- (pattern) => {
224
- if (isBareSpecifier(pattern)) {
225
- try {
226
- if (pattern.endsWith("/")) {
227
- // avoid package path not exported
228
- const { packageDirectoryUrl } = applyNodeEsmResolution({
229
- specifier: pattern.slice(0, -1),
230
- parentUrl: rootDirectoryUrl,
231
- });
232
- return packageDirectoryUrl;
293
+ custom_resolvers_from_package_conditions: {
294
+ for (const key of Object.keys(packageConditions)) {
295
+ const value = packageConditions[key];
296
+ let customResolver;
297
+ if (typeof value === "object") {
298
+ const associations = URL_META.resolveAssociations(
299
+ { applies: value },
300
+ (pattern) => {
301
+ if (isBareSpecifier(pattern)) {
302
+ try {
303
+ if (pattern.endsWith("/")) {
304
+ // avoid package path not exported
305
+ const { packageDirectoryUrl } = applyNodeEsmResolution({
306
+ specifier: pattern.slice(0, -1),
307
+ parentUrl: rootDirectoryUrl,
308
+ });
309
+ return packageDirectoryUrl;
310
+ }
311
+ const { url } = applyNodeEsmResolution({
312
+ specifier: pattern,
313
+ parentUrl: rootDirectoryUrl,
314
+ });
315
+ return url;
316
+ } catch {
317
+ return new URL(pattern, rootDirectoryUrl);
318
+ }
233
319
  }
234
- const { url } = applyNodeEsmResolution({
235
- specifier: pattern,
236
- parentUrl: rootDirectoryUrl,
237
- });
238
- return url;
239
- } catch {
240
320
  return new URL(pattern, rootDirectoryUrl);
321
+ },
322
+ );
323
+ customResolver = (specifier, importer, { resolver }) => {
324
+ if (isBareSpecifier(specifier)) {
325
+ const { url } = resolver({
326
+ specifier,
327
+ parentUrl: importer,
328
+ });
329
+ const { applies } = URL_META.applyAssociations({
330
+ url,
331
+ associations,
332
+ });
333
+ return applies;
241
334
  }
242
- }
243
- return new URL(pattern, rootDirectoryUrl);
244
- },
245
- );
246
- customResolver = (specifier, importer) => {
247
- if (isBareSpecifier(specifier)) {
248
- const { url } = applyNodeEsmResolution({
249
- specifier,
250
- parentUrl: importer,
251
- });
252
- const { applies } = URL_META.applyAssociations({ url, associations });
253
- return applies;
335
+ const { applies } = URL_META.applyAssociations({
336
+ url: importer,
337
+ associations,
338
+ });
339
+ return applies;
340
+ };
341
+ } else if (typeof value === "function") {
342
+ customResolver = value;
343
+ } else {
344
+ customResolver = value;
254
345
  }
255
- return URL_META.applyAssociations({ url: importer, associations })
256
- .applies;
257
- };
258
- } else if (typeof value === "function") {
259
- customResolver = value;
260
- } else {
261
- customResolver = value;
346
+ addCustomResolver(key, customResolver);
347
+ }
348
+ }
349
+ for (const wildcardToRemove of wildcardToRemoveSet) {
350
+ delete conditionResolvers[wildcardToRemove];
262
351
  }
263
- addCustomResolver(customCondition, customResolver);
264
- }
265
-
266
- for (const wildcardToRemove of wildcardToRemoveSet) {
267
- delete conditionResolvers[wildcardToRemove];
268
- }
269
352
 
270
- const conditionCandidateArray = Object.keys(conditionResolvers);
271
- return (specifier, importer, params) => {
272
- const conditions = [];
273
- for (const conditionCandidate of conditionCandidateArray) {
274
- const conditionResolver = conditionResolvers[conditionCandidate];
275
- if (typeof conditionResolver === "function") {
276
- if (conditionResolver(specifier, importer, params)) {
353
+ const conditionCandidateArray = Object.keys(conditionResolvers);
354
+ resolveConditionsFromContext = (specifier, importer, params) => {
355
+ const conditions = [];
356
+ for (const conditionCandidate of conditionCandidateArray) {
357
+ const conditionResolver = conditionResolvers[conditionCandidate];
358
+ if (typeof conditionResolver === "function") {
359
+ if (conditionResolver(specifier, importer, params)) {
360
+ conditions.push(conditionCandidate);
361
+ }
362
+ } else if (conditionResolver) {
277
363
  conditions.push(conditionCandidate);
278
364
  }
279
- } else if (conditionResolver) {
280
- conditions.push(conditionCandidate);
281
365
  }
366
+ return conditions;
367
+ };
368
+ }
369
+
370
+ return (specifier, importer, params) => {
371
+ const conditionsForThisSpecifier = resolveConditionsFromSpecifier(
372
+ specifier,
373
+ importer,
374
+ params,
375
+ );
376
+ if (conditionsForThisSpecifier) {
377
+ return conditionsForThisSpecifier;
378
+ }
379
+ const conditionsFromContext = resolveConditionsFromContext(
380
+ specifier,
381
+ importer,
382
+ params,
383
+ );
384
+ if (conditionsFromContext) {
385
+ return conditionsFromContext;
282
386
  }
283
- return conditions;
387
+ return [];
284
388
  };
285
389
  };
286
390
 
@@ -334,6 +438,16 @@ const addRelationshipWithPackageJson = ({
334
438
  }
335
439
  };
336
440
 
441
+ const createResolverWithFallbackOnError = (mainResolver, fallbackResolver) => {
442
+ return (params) => {
443
+ try {
444
+ return mainResolver(params);
445
+ } catch {
446
+ return fallbackResolver(params);
447
+ }
448
+ };
449
+ };
450
+
337
451
  const isBareSpecifier = (specifier) => {
338
452
  if (
339
453
  specifier[0] === "/" ||