@jsenv/test 1.2.4 → 1.3.1

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.
@@ -4,129 +4,147 @@ import { pathToFileURL } from "node:url";
4
4
  // duplicated from @jsenv/log to avoid the dependency
5
5
  const createDetailedMessage = (message, details = {}) => {
6
6
  let string = `${message}`;
7
- Object.keys(details).forEach(key => {
7
+
8
+ Object.keys(details).forEach((key) => {
8
9
  const value = details[key];
9
10
  string += `
10
11
  --- ${key} ---
11
- ${Array.isArray(value) ? value.join(`
12
- `) : value}`;
12
+ ${
13
+ Array.isArray(value)
14
+ ? value.join(`
15
+ `)
16
+ : value
17
+ }`;
13
18
  });
14
- return string;
19
+
20
+ return string
15
21
  };
16
22
 
17
- const assertImportMap = value => {
23
+ const assertImportMap = (value) => {
18
24
  if (value === null) {
19
- throw new TypeError(`an importMap must be an object, got null`);
25
+ throw new TypeError(`an importMap must be an object, got null`)
20
26
  }
27
+
21
28
  const type = typeof value;
22
29
  if (type !== "object") {
23
- throw new TypeError(`an importMap must be an object, received ${value}`);
30
+ throw new TypeError(`an importMap must be an object, received ${value}`)
24
31
  }
32
+
25
33
  if (Array.isArray(value)) {
26
- throw new TypeError(`an importMap must be an object, received array ${value}`);
34
+ throw new TypeError(
35
+ `an importMap must be an object, received array ${value}`,
36
+ )
27
37
  }
28
38
  };
29
39
 
30
- const hasScheme = string => {
31
- return /^[a-zA-Z]{2,}:/.test(string);
40
+ const hasScheme = (string) => {
41
+ return /^[a-zA-Z]{2,}:/.test(string)
32
42
  };
33
43
 
34
- const urlToScheme = urlString => {
44
+ const urlToScheme = (urlString) => {
35
45
  const colonIndex = urlString.indexOf(":");
36
- if (colonIndex === -1) return "";
37
- return urlString.slice(0, colonIndex);
46
+ if (colonIndex === -1) return ""
47
+ return urlString.slice(0, colonIndex)
38
48
  };
39
49
 
40
- const urlToPathname = urlString => {
41
- return ressourceToPathname(urlToRessource(urlString));
50
+ const urlToPathname = (urlString) => {
51
+ return ressourceToPathname(urlToRessource(urlString))
42
52
  };
43
- const urlToRessource = urlString => {
53
+
54
+ const urlToRessource = (urlString) => {
44
55
  const scheme = urlToScheme(urlString);
56
+
45
57
  if (scheme === "file") {
46
- return urlString.slice("file://".length);
58
+ return urlString.slice("file://".length)
47
59
  }
60
+
48
61
  if (scheme === "https" || scheme === "http") {
49
62
  // remove origin
50
63
  const afterProtocol = urlString.slice(scheme.length + "://".length);
51
64
  const pathnameSlashIndex = afterProtocol.indexOf("/", "://".length);
52
- return afterProtocol.slice(pathnameSlashIndex);
65
+ return afterProtocol.slice(pathnameSlashIndex)
53
66
  }
54
- return urlString.slice(scheme.length + 1);
67
+
68
+ return urlString.slice(scheme.length + 1)
55
69
  };
56
- const ressourceToPathname = ressource => {
70
+
71
+ const ressourceToPathname = (ressource) => {
57
72
  const searchSeparatorIndex = ressource.indexOf("?");
58
- return searchSeparatorIndex === -1 ? ressource : ressource.slice(0, searchSeparatorIndex);
73
+ return searchSeparatorIndex === -1
74
+ ? ressource
75
+ : ressource.slice(0, searchSeparatorIndex)
59
76
  };
60
77
 
61
- const urlToOrigin = urlString => {
78
+ const urlToOrigin = (urlString) => {
62
79
  const scheme = urlToScheme(urlString);
80
+
63
81
  if (scheme === "file") {
64
- return "file://";
82
+ return "file://"
65
83
  }
84
+
66
85
  if (scheme === "http" || scheme === "https") {
67
86
  const secondProtocolSlashIndex = scheme.length + "://".length;
68
87
  const pathnameSlashIndex = urlString.indexOf("/", secondProtocolSlashIndex);
69
- if (pathnameSlashIndex === -1) return urlString;
70
- return urlString.slice(0, pathnameSlashIndex);
88
+
89
+ if (pathnameSlashIndex === -1) return urlString
90
+ return urlString.slice(0, pathnameSlashIndex)
71
91
  }
72
- return urlString.slice(0, scheme.length + 1);
92
+
93
+ return urlString.slice(0, scheme.length + 1)
73
94
  };
74
95
 
75
- const pathnameToParentPathname = pathname => {
96
+ const pathnameToParentPathname = (pathname) => {
76
97
  const slashLastIndex = pathname.lastIndexOf("/");
77
98
  if (slashLastIndex === -1) {
78
- return "/";
99
+ return "/"
79
100
  }
80
- return pathname.slice(0, slashLastIndex + 1);
101
+
102
+ return pathname.slice(0, slashLastIndex + 1)
81
103
  };
82
104
 
83
105
  // could be useful: https://url.spec.whatwg.org/#url-miscellaneous
84
106
 
107
+
85
108
  const resolveUrl = (specifier, baseUrl) => {
86
109
  if (baseUrl) {
87
110
  if (typeof baseUrl !== "string") {
88
- throw new TypeError(writeBaseUrlMustBeAString({
89
- baseUrl,
90
- specifier
91
- }));
111
+ throw new TypeError(writeBaseUrlMustBeAString({ baseUrl, specifier }))
92
112
  }
93
113
  if (!hasScheme(baseUrl)) {
94
- throw new Error(writeBaseUrlMustBeAbsolute({
95
- baseUrl,
96
- specifier
97
- }));
114
+ throw new Error(writeBaseUrlMustBeAbsolute({ baseUrl, specifier }))
98
115
  }
99
116
  }
117
+
100
118
  if (hasScheme(specifier)) {
101
- return specifier;
119
+ return specifier
102
120
  }
121
+
103
122
  if (!baseUrl) {
104
- throw new Error(writeBaseUrlRequired({
105
- baseUrl,
106
- specifier
107
- }));
123
+ throw new Error(writeBaseUrlRequired({ baseUrl, specifier }))
108
124
  }
109
125
 
110
126
  // scheme relative
111
127
  if (specifier.slice(0, 2) === "//") {
112
- return `${urlToScheme(baseUrl)}:${specifier}`;
128
+ return `${urlToScheme(baseUrl)}:${specifier}`
113
129
  }
114
130
 
115
131
  // origin relative
116
132
  if (specifier[0] === "/") {
117
- return `${urlToOrigin(baseUrl)}${specifier}`;
133
+ return `${urlToOrigin(baseUrl)}${specifier}`
118
134
  }
135
+
119
136
  const baseOrigin = urlToOrigin(baseUrl);
120
137
  const basePathname = urlToPathname(baseUrl);
138
+
121
139
  if (specifier === ".") {
122
140
  const baseDirectoryPathname = pathnameToParentPathname(basePathname);
123
- return `${baseOrigin}${baseDirectoryPathname}`;
141
+ return `${baseOrigin}${baseDirectoryPathname}`
124
142
  }
125
143
 
126
144
  // pathname relative inside
127
145
  if (specifier.slice(0, 2) === "./") {
128
146
  const baseDirectoryPathname = pathnameToParentPathname(basePathname);
129
- return `${baseOrigin}${baseDirectoryPathname}${specifier.slice(2)}`;
147
+ return `${baseOrigin}${baseDirectoryPathname}${specifier.slice(2)}`
130
148
  }
131
149
 
132
150
  // pathname relative outside
@@ -134,6 +152,7 @@ const resolveUrl = (specifier, baseUrl) => {
134
152
  let unresolvedPathname = specifier;
135
153
  const importerFolders = basePathname.split("/");
136
154
  importerFolders.pop();
155
+
137
156
  while (unresolvedPathname.slice(0, 3) === "../") {
138
157
  unresolvedPathname = unresolvedPathname.slice(3);
139
158
  // when there is no folder left to resolved
@@ -142,38 +161,44 @@ const resolveUrl = (specifier, baseUrl) => {
142
161
  importerFolders.pop();
143
162
  }
144
163
  }
145
- const resolvedPathname = `${importerFolders.join("/")}/${unresolvedPathname}`;
146
- return `${baseOrigin}${resolvedPathname}`;
164
+
165
+ const resolvedPathname = `${importerFolders.join(
166
+ "/",
167
+ )}/${unresolvedPathname}`;
168
+ return `${baseOrigin}${resolvedPathname}`
147
169
  }
148
170
 
149
171
  // bare
150
172
  if (basePathname === "") {
151
- return `${baseOrigin}/${specifier}`;
173
+ return `${baseOrigin}/${specifier}`
152
174
  }
153
175
  if (basePathname[basePathname.length] === "/") {
154
- return `${baseOrigin}${basePathname}${specifier}`;
176
+ return `${baseOrigin}${basePathname}${specifier}`
155
177
  }
156
- return `${baseOrigin}${pathnameToParentPathname(basePathname)}${specifier}`;
178
+ return `${baseOrigin}${pathnameToParentPathname(basePathname)}${specifier}`
157
179
  };
180
+
158
181
  const writeBaseUrlMustBeAString = ({
159
182
  baseUrl,
160
- specifier
183
+ specifier,
161
184
  }) => `baseUrl must be a string.
162
185
  --- base url ---
163
186
  ${baseUrl}
164
187
  --- specifier ---
165
188
  ${specifier}`;
189
+
166
190
  const writeBaseUrlMustBeAbsolute = ({
167
191
  baseUrl,
168
- specifier
192
+ specifier,
169
193
  }) => `baseUrl must be absolute.
170
194
  --- base url ---
171
195
  ${baseUrl}
172
196
  --- specifier ---
173
197
  ${specifier}`;
198
+
174
199
  const writeBaseUrlRequired = ({
175
200
  baseUrl,
176
- specifier
201
+ specifier,
177
202
  }) => `baseUrl required to resolve relative specifier.
178
203
  --- base url ---
179
204
  ${baseUrl}
@@ -182,91 +207,123 @@ ${specifier}`;
182
207
 
183
208
  const tryUrlResolution = (string, url) => {
184
209
  const result = resolveUrl(string, url);
185
- return hasScheme(result) ? result : null;
210
+ return hasScheme(result) ? result : null
186
211
  };
187
212
 
188
213
  const resolveSpecifier = (specifier, importer) => {
189
- if (specifier === "." || specifier[0] === "/" || specifier.startsWith("./") || specifier.startsWith("../")) {
190
- return resolveUrl(specifier, importer);
214
+ if (
215
+ specifier === "." ||
216
+ specifier[0] === "/" ||
217
+ specifier.startsWith("./") ||
218
+ specifier.startsWith("../")
219
+ ) {
220
+ return resolveUrl(specifier, importer)
191
221
  }
222
+
192
223
  if (hasScheme(specifier)) {
193
- return specifier;
224
+ return specifier
194
225
  }
195
- return null;
226
+
227
+ return null
196
228
  };
197
229
 
198
230
  const applyImportMap = ({
199
231
  importMap,
200
232
  specifier,
201
233
  importer,
202
- createBareSpecifierError = ({
203
- specifier,
204
- importer
205
- }) => {
206
- return new Error(createDetailedMessage(`Unmapped bare specifier.`, {
207
- specifier,
208
- importer
209
- }));
234
+ createBareSpecifierError = ({ specifier, importer }) => {
235
+ return new Error(
236
+ createDetailedMessage(`Unmapped bare specifier.`, {
237
+ specifier,
238
+ importer,
239
+ }),
240
+ )
210
241
  },
211
- onImportMapping = () => {}
242
+ onImportMapping = () => {},
212
243
  }) => {
213
244
  assertImportMap(importMap);
214
245
  if (typeof specifier !== "string") {
215
- throw new TypeError(createDetailedMessage("specifier must be a string.", {
216
- specifier,
217
- importer
218
- }));
246
+ throw new TypeError(
247
+ createDetailedMessage("specifier must be a string.", {
248
+ specifier,
249
+ importer,
250
+ }),
251
+ )
219
252
  }
220
253
  if (importer) {
221
254
  if (typeof importer !== "string") {
222
- throw new TypeError(createDetailedMessage("importer must be a string.", {
223
- importer,
224
- specifier
225
- }));
255
+ throw new TypeError(
256
+ createDetailedMessage("importer must be a string.", {
257
+ importer,
258
+ specifier,
259
+ }),
260
+ )
226
261
  }
227
262
  if (!hasScheme(importer)) {
228
- throw new Error(createDetailedMessage(`importer must be an absolute url.`, {
229
- importer,
230
- specifier
231
- }));
263
+ throw new Error(
264
+ createDetailedMessage(`importer must be an absolute url.`, {
265
+ importer,
266
+ specifier,
267
+ }),
268
+ )
232
269
  }
233
270
  }
271
+
234
272
  const specifierUrl = resolveSpecifier(specifier, importer);
235
273
  const specifierNormalized = specifierUrl || specifier;
236
- const {
237
- scopes
238
- } = importMap;
274
+
275
+ const { scopes } = importMap;
239
276
  if (scopes && importer) {
240
- const scopeSpecifierMatching = Object.keys(scopes).find(scopeSpecifier => {
241
- return scopeSpecifier === importer || specifierIsPrefixOf(scopeSpecifier, importer);
242
- });
277
+ const scopeSpecifierMatching = Object.keys(scopes).find(
278
+ (scopeSpecifier) => {
279
+ return (
280
+ scopeSpecifier === importer ||
281
+ specifierIsPrefixOf(scopeSpecifier, importer)
282
+ )
283
+ },
284
+ );
243
285
  if (scopeSpecifierMatching) {
244
286
  const scopeMappings = scopes[scopeSpecifierMatching];
245
- const mappingFromScopes = applyMappings(scopeMappings, specifierNormalized, scopeSpecifierMatching, onImportMapping);
287
+ const mappingFromScopes = applyMappings(
288
+ scopeMappings,
289
+ specifierNormalized,
290
+ scopeSpecifierMatching,
291
+ onImportMapping,
292
+ );
246
293
  if (mappingFromScopes !== null) {
247
- return mappingFromScopes;
294
+ return mappingFromScopes
248
295
  }
249
296
  }
250
297
  }
251
- const {
252
- imports
253
- } = importMap;
298
+
299
+ const { imports } = importMap;
254
300
  if (imports) {
255
- const mappingFromImports = applyMappings(imports, specifierNormalized, undefined, onImportMapping);
301
+ const mappingFromImports = applyMappings(
302
+ imports,
303
+ specifierNormalized,
304
+ undefined,
305
+ onImportMapping,
306
+ );
256
307
  if (mappingFromImports !== null) {
257
- return mappingFromImports;
308
+ return mappingFromImports
258
309
  }
259
310
  }
311
+
260
312
  if (specifierUrl) {
261
- return specifierUrl;
313
+ return specifierUrl
262
314
  }
263
- throw createBareSpecifierError({
264
- specifier,
265
- importer
266
- });
315
+
316
+ throw createBareSpecifierError({ specifier, importer })
267
317
  };
268
- const applyMappings = (mappings, specifierNormalized, scope, onImportMapping) => {
318
+
319
+ const applyMappings = (
320
+ mappings,
321
+ specifierNormalized,
322
+ scope,
323
+ onImportMapping,
324
+ ) => {
269
325
  const specifierCandidates = Object.keys(mappings);
326
+
270
327
  let i = 0;
271
328
  while (i < specifierCandidates.length) {
272
329
  const specifierCandidate = specifierCandidates[i];
@@ -278,140 +335,179 @@ const applyMappings = (mappings, specifierNormalized, scope, onImportMapping) =>
278
335
  from: specifierCandidate,
279
336
  to: address,
280
337
  before: specifierNormalized,
281
- after: address
338
+ after: address,
282
339
  });
283
- return address;
340
+ return address
284
341
  }
285
342
  if (specifierIsPrefixOf(specifierCandidate, specifierNormalized)) {
286
343
  const address = mappings[specifierCandidate];
287
- const afterSpecifier = specifierNormalized.slice(specifierCandidate.length);
344
+ const afterSpecifier = specifierNormalized.slice(
345
+ specifierCandidate.length,
346
+ );
288
347
  const addressFinal = tryUrlResolution(afterSpecifier, address);
289
348
  onImportMapping({
290
349
  scope,
291
350
  from: specifierCandidate,
292
351
  to: address,
293
352
  before: specifierNormalized,
294
- after: addressFinal
353
+ after: addressFinal,
295
354
  });
296
- return addressFinal;
355
+ return addressFinal
297
356
  }
298
357
  }
299
- return null;
358
+
359
+ return null
300
360
  };
361
+
301
362
  const specifierIsPrefixOf = (specifierHref, href) => {
302
- return specifierHref[specifierHref.length - 1] === "/" && href.startsWith(specifierHref);
363
+ return (
364
+ specifierHref[specifierHref.length - 1] === "/" &&
365
+ href.startsWith(specifierHref)
366
+ )
303
367
  };
304
368
 
305
- const sortImports = imports => {
369
+ const sortImports = (imports) => {
306
370
  const mappingsSorted = {};
307
- Object.keys(imports).sort(compareLengthOrLocaleCompare).forEach(name => {
308
- mappingsSorted[name] = imports[name];
309
- });
310
- return mappingsSorted;
371
+
372
+ Object.keys(imports)
373
+ .sort(compareLengthOrLocaleCompare)
374
+ .forEach((name) => {
375
+ mappingsSorted[name] = imports[name];
376
+ });
377
+
378
+ return mappingsSorted
311
379
  };
312
- const sortScopes = scopes => {
380
+
381
+ const sortScopes = (scopes) => {
313
382
  const scopesSorted = {};
314
- Object.keys(scopes).sort(compareLengthOrLocaleCompare).forEach(scopeSpecifier => {
315
- scopesSorted[scopeSpecifier] = sortImports(scopes[scopeSpecifier]);
316
- });
317
- return scopesSorted;
383
+
384
+ Object.keys(scopes)
385
+ .sort(compareLengthOrLocaleCompare)
386
+ .forEach((scopeSpecifier) => {
387
+ scopesSorted[scopeSpecifier] = sortImports(scopes[scopeSpecifier]);
388
+ });
389
+
390
+ return scopesSorted
318
391
  };
392
+
319
393
  const compareLengthOrLocaleCompare = (a, b) => {
320
- return b.length - a.length || a.localeCompare(b);
394
+ return b.length - a.length || a.localeCompare(b)
321
395
  };
322
396
 
323
397
  const normalizeImportMap = (importMap, baseUrl) => {
324
398
  assertImportMap(importMap);
399
+
325
400
  if (!isStringOrUrl(baseUrl)) {
326
- throw new TypeError(formulateBaseUrlMustBeStringOrUrl({
327
- baseUrl
328
- }));
329
- }
330
- const {
331
- imports,
332
- scopes
333
- } = importMap;
401
+ throw new TypeError(formulateBaseUrlMustBeStringOrUrl({ baseUrl }))
402
+ }
403
+
404
+ const { imports, scopes } = importMap;
405
+
334
406
  return {
335
407
  imports: imports ? normalizeMappings(imports, baseUrl) : undefined,
336
- scopes: scopes ? normalizeScopes(scopes, baseUrl) : undefined
337
- };
408
+ scopes: scopes ? normalizeScopes(scopes, baseUrl) : undefined,
409
+ }
338
410
  };
339
- const isStringOrUrl = value => {
411
+
412
+ const isStringOrUrl = (value) => {
340
413
  if (typeof value === "string") {
341
- return true;
414
+ return true
342
415
  }
416
+
343
417
  if (typeof URL === "function" && value instanceof URL) {
344
- return true;
418
+ return true
345
419
  }
346
- return false;
420
+
421
+ return false
347
422
  };
423
+
348
424
  const normalizeMappings = (mappings, baseUrl) => {
349
425
  const mappingsNormalized = {};
350
- Object.keys(mappings).forEach(specifier => {
426
+
427
+ Object.keys(mappings).forEach((specifier) => {
351
428
  const address = mappings[specifier];
429
+
352
430
  if (typeof address !== "string") {
353
- console.warn(formulateAddressMustBeAString({
354
- address,
355
- specifier
356
- }));
357
- return;
431
+ console.warn(
432
+ formulateAddressMustBeAString({
433
+ address,
434
+ specifier,
435
+ }),
436
+ );
437
+ return
358
438
  }
439
+
359
440
  const specifierResolved = resolveSpecifier(specifier, baseUrl) || specifier;
441
+
360
442
  const addressUrl = tryUrlResolution(address, baseUrl);
361
443
  if (addressUrl === null) {
362
- console.warn(formulateAdressResolutionFailed({
363
- address,
364
- baseUrl,
365
- specifier
366
- }));
367
- return;
444
+ console.warn(
445
+ formulateAdressResolutionFailed({
446
+ address,
447
+ baseUrl,
448
+ specifier,
449
+ }),
450
+ );
451
+ return
368
452
  }
453
+
369
454
  if (specifier.endsWith("/") && !addressUrl.endsWith("/")) {
370
- console.warn(formulateAddressUrlRequiresTrailingSlash({
371
- addressUrl,
372
- address,
373
- specifier
374
- }));
375
- return;
455
+ console.warn(
456
+ formulateAddressUrlRequiresTrailingSlash({
457
+ addressUrl,
458
+ address,
459
+ specifier,
460
+ }),
461
+ );
462
+ return
376
463
  }
377
464
  mappingsNormalized[specifierResolved] = addressUrl;
378
465
  });
379
- return sortImports(mappingsNormalized);
466
+
467
+ return sortImports(mappingsNormalized)
380
468
  };
469
+
381
470
  const normalizeScopes = (scopes, baseUrl) => {
382
471
  const scopesNormalized = {};
383
- Object.keys(scopes).forEach(scopeSpecifier => {
472
+
473
+ Object.keys(scopes).forEach((scopeSpecifier) => {
384
474
  const scopeMappings = scopes[scopeSpecifier];
385
475
  const scopeUrl = tryUrlResolution(scopeSpecifier, baseUrl);
386
476
  if (scopeUrl === null) {
387
- console.warn(formulateScopeResolutionFailed({
388
- scope: scopeSpecifier,
389
- baseUrl
390
- }));
391
- return;
477
+ console.warn(
478
+ formulateScopeResolutionFailed({
479
+ scope: scopeSpecifier,
480
+ baseUrl,
481
+ }),
482
+ );
483
+ return
392
484
  }
393
485
  const scopeValueNormalized = normalizeMappings(scopeMappings, baseUrl);
394
486
  scopesNormalized[scopeUrl] = scopeValueNormalized;
395
487
  });
396
- return sortScopes(scopesNormalized);
488
+
489
+ return sortScopes(scopesNormalized)
397
490
  };
491
+
398
492
  const formulateBaseUrlMustBeStringOrUrl = ({
399
- baseUrl
493
+ baseUrl,
400
494
  }) => `baseUrl must be a string or an url.
401
495
  --- base url ---
402
496
  ${baseUrl}`;
497
+
403
498
  const formulateAddressMustBeAString = ({
404
499
  specifier,
405
- address
500
+ address,
406
501
  }) => `Address must be a string.
407
502
  --- address ---
408
503
  ${address}
409
504
  --- specifier ---
410
505
  ${specifier}`;
506
+
411
507
  const formulateAdressResolutionFailed = ({
412
508
  address,
413
509
  baseUrl,
414
- specifier
510
+ specifier,
415
511
  }) => `Address url resolution failed.
416
512
  --- address ---
417
513
  ${address}
@@ -419,10 +515,11 @@ ${address}
419
515
  ${baseUrl}
420
516
  --- specifier ---
421
517
  ${specifier}`;
518
+
422
519
  const formulateAddressUrlRequiresTrailingSlash = ({
423
520
  addressURL,
424
521
  address,
425
- specifier
522
+ specifier,
426
523
  }) => `Address must end with /.
427
524
  --- address url ---
428
525
  ${addressURL}
@@ -430,24 +527,26 @@ ${addressURL}
430
527
  ${address}
431
528
  --- specifier ---
432
529
  ${specifier}`;
530
+
433
531
  const formulateScopeResolutionFailed = ({
434
532
  scope,
435
- baseUrl
533
+ baseUrl,
436
534
  }) => `Scope url resolution failed.
437
535
  --- scope ---
438
536
  ${scope}
439
537
  --- base url ---
440
538
  ${baseUrl}`;
441
539
 
442
- const pathnameToExtension = pathname => {
540
+ const pathnameToExtension = (pathname) => {
443
541
  const slashLastIndex = pathname.lastIndexOf("/");
444
542
  if (slashLastIndex !== -1) {
445
543
  pathname = pathname.slice(slashLastIndex + 1);
446
544
  }
545
+
447
546
  const dotLastIndex = pathname.lastIndexOf(".");
448
- if (dotLastIndex === -1) return "";
547
+ if (dotLastIndex === -1) return ""
449
548
  // if (dotLastIndex === pathname.length - 1) return ""
450
- return pathname.slice(dotLastIndex);
549
+ return pathname.slice(dotLastIndex)
451
550
  };
452
551
 
453
552
  const resolveImport = ({
@@ -456,7 +555,7 @@ const resolveImport = ({
456
555
  importMap,
457
556
  defaultExtension = false,
458
557
  createBareSpecifierError,
459
- onImportMapping = () => {}
558
+ onImportMapping = () => {},
460
559
  }) => {
461
560
  let url;
462
561
  if (importMap) {
@@ -465,48 +564,48 @@ const resolveImport = ({
465
564
  specifier,
466
565
  importer,
467
566
  createBareSpecifierError,
468
- onImportMapping
567
+ onImportMapping,
469
568
  });
470
569
  } else {
471
570
  url = resolveUrl(specifier, importer);
472
571
  }
572
+
473
573
  if (defaultExtension) {
474
- url = applyDefaultExtension({
475
- url,
476
- importer,
477
- defaultExtension
478
- });
574
+ url = applyDefaultExtension({ url, importer, defaultExtension });
479
575
  }
480
- return url;
576
+
577
+ return url
481
578
  };
482
- const applyDefaultExtension = ({
483
- url,
484
- importer,
485
- defaultExtension
486
- }) => {
579
+
580
+ const applyDefaultExtension = ({ url, importer, defaultExtension }) => {
487
581
  if (urlToPathname(url).endsWith("/")) {
488
- return url;
582
+ return url
489
583
  }
584
+
490
585
  if (typeof defaultExtension === "string") {
491
586
  const extension = pathnameToExtension(url);
492
587
  if (extension === "") {
493
- return `${url}${defaultExtension}`;
588
+ return `${url}${defaultExtension}`
494
589
  }
495
- return url;
590
+ return url
496
591
  }
592
+
497
593
  if (defaultExtension === true) {
498
594
  const extension = pathnameToExtension(url);
499
595
  if (extension === "" && importer) {
500
596
  const importerPathname = urlToPathname(importer);
501
597
  const importerExtension = pathnameToExtension(importerPathname);
502
- return `${url}${importerExtension}`;
598
+ return `${url}${importerExtension}`
503
599
  }
504
600
  }
505
- return url;
601
+
602
+ return url
506
603
  };
507
604
 
508
605
  let importMap;
606
+
509
607
  const cwdUrl = `${String(pathToFileURL(process.cwd()))}/`;
608
+
510
609
  if (process.env.IMPORT_MAP) {
511
610
  importMap = JSON.parse(process.env.IMPORT_MAP);
512
611
  } else if (process.env.IMPORT_MAP_PATH) {
@@ -518,8 +617,10 @@ if (process.env.IMPORT_MAP) {
518
617
  const importmapFileContentAsString = readFileSync(importmapFileUrl, "utf8");
519
618
  importMap = JSON.parse(importmapFileContentAsString);
520
619
  }
620
+
521
621
  const importMapBaseUrl = process.env.IMPORT_MAP_BASE_URL || cwdUrl;
522
622
  importMap = normalizeImportMap(importMap, importMapBaseUrl);
623
+
523
624
  const resolve = (specifier, context, nextResolve) => {
524
625
  try {
525
626
  let mapped;
@@ -531,12 +632,12 @@ const resolve = (specifier, context, nextResolve) => {
531
632
  defaultExtension: ".js",
532
633
  onImportMapping: () => {
533
634
  mapped = true;
534
- }
635
+ },
535
636
  });
536
637
  if (mapped) {
537
638
  return {
538
639
  shortCircuit: true,
539
- url: resolved
640
+ url: resolved,
540
641
  };
541
642
  }
542
643
  } catch (e) {