@jsenv/test 3.7.2 → 3.7.4
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.
- package/dist/exception.js +1 -1
- package/dist/js/importmap_hooks.mjs +102 -102
- package/dist/jsenv_test.js +61 -61
- package/package.json +24 -14
package/dist/exception.js
CHANGED
|
@@ -633,7 +633,7 @@ const isDev = process.execArgv.some(
|
|
|
633
633
|
const createException = (
|
|
634
634
|
reason,
|
|
635
635
|
{
|
|
636
|
-
jsenvCoreDirectoryUrl =
|
|
636
|
+
jsenvCoreDirectoryUrl = import.meta.resolve("../../../../"),
|
|
637
637
|
rootDirectoryUrl,
|
|
638
638
|
errorTransform = () => {},
|
|
639
639
|
} = {},
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
3
|
|
|
4
|
+
const assertImportMap = (value) => {
|
|
5
|
+
if (value === null) {
|
|
6
|
+
throw new TypeError(`an importMap must be an object, got null`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const type = typeof value;
|
|
10
|
+
if (type !== "object") {
|
|
11
|
+
throw new TypeError(`an importMap must be an object, received ${value}`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (Array.isArray(value)) {
|
|
15
|
+
throw new TypeError(
|
|
16
|
+
`an importMap must be an object, received array ${value}`,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
4
21
|
// duplicated from @jsenv/log to avoid the dependency
|
|
5
22
|
const createDetailedMessage = (message, details = {}) => {
|
|
6
23
|
let string = `${message}`;
|
|
@@ -17,89 +34,72 @@ const createDetailedMessage = (message, details = {}) => {
|
|
|
17
34
|
}`;
|
|
18
35
|
});
|
|
19
36
|
|
|
20
|
-
return string
|
|
37
|
+
return string;
|
|
21
38
|
};
|
|
22
39
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const type = typeof value;
|
|
29
|
-
if (type !== "object") {
|
|
30
|
-
throw new TypeError(`an importMap must be an object, received ${value}`)
|
|
31
|
-
}
|
|
40
|
+
const hasScheme = (string) => {
|
|
41
|
+
return /^[a-zA-Z]{2,}:/.test(string);
|
|
42
|
+
};
|
|
32
43
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
const pathnameToParentPathname = (pathname) => {
|
|
45
|
+
const slashLastIndex = pathname.lastIndexOf("/");
|
|
46
|
+
if (slashLastIndex === -1) {
|
|
47
|
+
return "/";
|
|
37
48
|
}
|
|
38
|
-
};
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
return /^[a-zA-Z]{2,}:/.test(string)
|
|
50
|
+
return pathname.slice(0, slashLastIndex + 1);
|
|
42
51
|
};
|
|
43
52
|
|
|
44
53
|
const urlToScheme = (urlString) => {
|
|
45
54
|
const colonIndex = urlString.indexOf(":");
|
|
46
|
-
if (colonIndex === -1) return ""
|
|
47
|
-
return urlString.slice(0, colonIndex)
|
|
55
|
+
if (colonIndex === -1) return "";
|
|
56
|
+
return urlString.slice(0, colonIndex);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const urlToOrigin = (urlString) => {
|
|
60
|
+
const scheme = urlToScheme(urlString);
|
|
61
|
+
|
|
62
|
+
if (scheme === "file") {
|
|
63
|
+
return "file://";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (scheme === "http" || scheme === "https") {
|
|
67
|
+
const secondProtocolSlashIndex = scheme.length + "://".length;
|
|
68
|
+
const pathnameSlashIndex = urlString.indexOf("/", secondProtocolSlashIndex);
|
|
69
|
+
|
|
70
|
+
if (pathnameSlashIndex === -1) return urlString;
|
|
71
|
+
return urlString.slice(0, pathnameSlashIndex);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return urlString.slice(0, scheme.length + 1);
|
|
48
75
|
};
|
|
49
76
|
|
|
50
77
|
const urlToPathname = (urlString) => {
|
|
51
|
-
return ressourceToPathname(urlToRessource(urlString))
|
|
78
|
+
return ressourceToPathname(urlToRessource(urlString));
|
|
52
79
|
};
|
|
53
80
|
|
|
54
81
|
const urlToRessource = (urlString) => {
|
|
55
82
|
const scheme = urlToScheme(urlString);
|
|
56
83
|
|
|
57
84
|
if (scheme === "file") {
|
|
58
|
-
return urlString.slice("file://".length)
|
|
85
|
+
return urlString.slice("file://".length);
|
|
59
86
|
}
|
|
60
87
|
|
|
61
88
|
if (scheme === "https" || scheme === "http") {
|
|
62
89
|
// remove origin
|
|
63
90
|
const afterProtocol = urlString.slice(scheme.length + "://".length);
|
|
64
91
|
const pathnameSlashIndex = afterProtocol.indexOf("/", "://".length);
|
|
65
|
-
return afterProtocol.slice(pathnameSlashIndex)
|
|
92
|
+
return afterProtocol.slice(pathnameSlashIndex);
|
|
66
93
|
}
|
|
67
94
|
|
|
68
|
-
return urlString.slice(scheme.length + 1)
|
|
95
|
+
return urlString.slice(scheme.length + 1);
|
|
69
96
|
};
|
|
70
97
|
|
|
71
98
|
const ressourceToPathname = (ressource) => {
|
|
72
99
|
const searchSeparatorIndex = ressource.indexOf("?");
|
|
73
100
|
return searchSeparatorIndex === -1
|
|
74
101
|
? ressource
|
|
75
|
-
: ressource.slice(0, searchSeparatorIndex)
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const urlToOrigin = (urlString) => {
|
|
79
|
-
const scheme = urlToScheme(urlString);
|
|
80
|
-
|
|
81
|
-
if (scheme === "file") {
|
|
82
|
-
return "file://"
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (scheme === "http" || scheme === "https") {
|
|
86
|
-
const secondProtocolSlashIndex = scheme.length + "://".length;
|
|
87
|
-
const pathnameSlashIndex = urlString.indexOf("/", secondProtocolSlashIndex);
|
|
88
|
-
|
|
89
|
-
if (pathnameSlashIndex === -1) return urlString
|
|
90
|
-
return urlString.slice(0, pathnameSlashIndex)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return urlString.slice(0, scheme.length + 1)
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
const pathnameToParentPathname = (pathname) => {
|
|
97
|
-
const slashLastIndex = pathname.lastIndexOf("/");
|
|
98
|
-
if (slashLastIndex === -1) {
|
|
99
|
-
return "/"
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return pathname.slice(0, slashLastIndex + 1)
|
|
102
|
+
: ressource.slice(0, searchSeparatorIndex);
|
|
103
103
|
};
|
|
104
104
|
|
|
105
105
|
// could be useful: https://url.spec.whatwg.org/#url-miscellaneous
|
|
@@ -108,29 +108,29 @@ const pathnameToParentPathname = (pathname) => {
|
|
|
108
108
|
const resolveUrl = (specifier, baseUrl) => {
|
|
109
109
|
if (baseUrl) {
|
|
110
110
|
if (typeof baseUrl !== "string") {
|
|
111
|
-
throw new TypeError(writeBaseUrlMustBeAString({ baseUrl, specifier }))
|
|
111
|
+
throw new TypeError(writeBaseUrlMustBeAString({ baseUrl, specifier }));
|
|
112
112
|
}
|
|
113
113
|
if (!hasScheme(baseUrl)) {
|
|
114
|
-
throw new Error(writeBaseUrlMustBeAbsolute({ baseUrl, specifier }))
|
|
114
|
+
throw new Error(writeBaseUrlMustBeAbsolute({ baseUrl, specifier }));
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
if (hasScheme(specifier)) {
|
|
119
|
-
return specifier
|
|
119
|
+
return specifier;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
if (!baseUrl) {
|
|
123
|
-
throw new Error(writeBaseUrlRequired({ baseUrl, specifier }))
|
|
123
|
+
throw new Error(writeBaseUrlRequired({ baseUrl, specifier }));
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
// scheme relative
|
|
127
127
|
if (specifier.slice(0, 2) === "//") {
|
|
128
|
-
return `${urlToScheme(baseUrl)}:${specifier}
|
|
128
|
+
return `${urlToScheme(baseUrl)}:${specifier}`;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// origin relative
|
|
132
132
|
if (specifier[0] === "/") {
|
|
133
|
-
return `${urlToOrigin(baseUrl)}${specifier}
|
|
133
|
+
return `${urlToOrigin(baseUrl)}${specifier}`;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
const baseOrigin = urlToOrigin(baseUrl);
|
|
@@ -138,13 +138,13 @@ const resolveUrl = (specifier, baseUrl) => {
|
|
|
138
138
|
|
|
139
139
|
if (specifier === ".") {
|
|
140
140
|
const baseDirectoryPathname = pathnameToParentPathname(basePathname);
|
|
141
|
-
return `${baseOrigin}${baseDirectoryPathname}
|
|
141
|
+
return `${baseOrigin}${baseDirectoryPathname}`;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
// pathname relative inside
|
|
145
145
|
if (specifier.slice(0, 2) === "./") {
|
|
146
146
|
const baseDirectoryPathname = pathnameToParentPathname(basePathname);
|
|
147
|
-
return `${baseOrigin}${baseDirectoryPathname}${specifier.slice(2)}
|
|
147
|
+
return `${baseOrigin}${baseDirectoryPathname}${specifier.slice(2)}`;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// pathname relative outside
|
|
@@ -165,17 +165,17 @@ const resolveUrl = (specifier, baseUrl) => {
|
|
|
165
165
|
const resolvedPathname = `${importerFolders.join(
|
|
166
166
|
"/",
|
|
167
167
|
)}/${unresolvedPathname}`;
|
|
168
|
-
return `${baseOrigin}${resolvedPathname}
|
|
168
|
+
return `${baseOrigin}${resolvedPathname}`;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
// bare
|
|
172
172
|
if (basePathname === "") {
|
|
173
|
-
return `${baseOrigin}/${specifier}
|
|
173
|
+
return `${baseOrigin}/${specifier}`;
|
|
174
174
|
}
|
|
175
175
|
if (basePathname[basePathname.length] === "/") {
|
|
176
|
-
return `${baseOrigin}${basePathname}${specifier}
|
|
176
|
+
return `${baseOrigin}${basePathname}${specifier}`;
|
|
177
177
|
}
|
|
178
|
-
return `${baseOrigin}${pathnameToParentPathname(basePathname)}${specifier}
|
|
178
|
+
return `${baseOrigin}${pathnameToParentPathname(basePathname)}${specifier}`;
|
|
179
179
|
};
|
|
180
180
|
|
|
181
181
|
const writeBaseUrlMustBeAString = ({
|
|
@@ -207,7 +207,7 @@ ${specifier}`;
|
|
|
207
207
|
|
|
208
208
|
const tryUrlResolution = (string, url) => {
|
|
209
209
|
const result = resolveUrl(string, url);
|
|
210
|
-
return hasScheme(result) ? result : null
|
|
210
|
+
return hasScheme(result) ? result : null;
|
|
211
211
|
};
|
|
212
212
|
|
|
213
213
|
const resolveSpecifier = (specifier, importer) => {
|
|
@@ -217,14 +217,14 @@ const resolveSpecifier = (specifier, importer) => {
|
|
|
217
217
|
specifier.startsWith("./") ||
|
|
218
218
|
specifier.startsWith("../")
|
|
219
219
|
) {
|
|
220
|
-
return resolveUrl(specifier, importer)
|
|
220
|
+
return resolveUrl(specifier, importer);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
if (hasScheme(specifier)) {
|
|
224
|
-
return specifier
|
|
224
|
+
return specifier;
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
return null
|
|
227
|
+
return null;
|
|
228
228
|
};
|
|
229
229
|
|
|
230
230
|
const applyImportMap = ({
|
|
@@ -237,7 +237,7 @@ const applyImportMap = ({
|
|
|
237
237
|
specifier,
|
|
238
238
|
importer,
|
|
239
239
|
}),
|
|
240
|
-
)
|
|
240
|
+
);
|
|
241
241
|
},
|
|
242
242
|
onImportMapping = () => {},
|
|
243
243
|
}) => {
|
|
@@ -248,7 +248,7 @@ const applyImportMap = ({
|
|
|
248
248
|
specifier,
|
|
249
249
|
importer,
|
|
250
250
|
}),
|
|
251
|
-
)
|
|
251
|
+
);
|
|
252
252
|
}
|
|
253
253
|
if (importer) {
|
|
254
254
|
if (typeof importer !== "string") {
|
|
@@ -257,7 +257,7 @@ const applyImportMap = ({
|
|
|
257
257
|
importer,
|
|
258
258
|
specifier,
|
|
259
259
|
}),
|
|
260
|
-
)
|
|
260
|
+
);
|
|
261
261
|
}
|
|
262
262
|
if (!hasScheme(importer)) {
|
|
263
263
|
throw new Error(
|
|
@@ -265,7 +265,7 @@ const applyImportMap = ({
|
|
|
265
265
|
importer,
|
|
266
266
|
specifier,
|
|
267
267
|
}),
|
|
268
|
-
)
|
|
268
|
+
);
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
|
|
@@ -279,7 +279,7 @@ const applyImportMap = ({
|
|
|
279
279
|
return (
|
|
280
280
|
scopeSpecifier === importer ||
|
|
281
281
|
specifierIsPrefixOf(scopeSpecifier, importer)
|
|
282
|
-
)
|
|
282
|
+
);
|
|
283
283
|
},
|
|
284
284
|
);
|
|
285
285
|
if (scopeSpecifierMatching) {
|
|
@@ -291,7 +291,7 @@ const applyImportMap = ({
|
|
|
291
291
|
onImportMapping,
|
|
292
292
|
);
|
|
293
293
|
if (mappingFromScopes !== null) {
|
|
294
|
-
return mappingFromScopes
|
|
294
|
+
return mappingFromScopes;
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
}
|
|
@@ -305,15 +305,15 @@ const applyImportMap = ({
|
|
|
305
305
|
onImportMapping,
|
|
306
306
|
);
|
|
307
307
|
if (mappingFromImports !== null) {
|
|
308
|
-
return mappingFromImports
|
|
308
|
+
return mappingFromImports;
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
if (specifierUrl) {
|
|
313
|
-
return specifierUrl
|
|
313
|
+
return specifierUrl;
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
-
throw createBareSpecifierError({ specifier, importer })
|
|
316
|
+
throw createBareSpecifierError({ specifier, importer });
|
|
317
317
|
};
|
|
318
318
|
|
|
319
319
|
const applyMappings = (
|
|
@@ -337,7 +337,7 @@ const applyMappings = (
|
|
|
337
337
|
before: specifierNormalized,
|
|
338
338
|
after: address,
|
|
339
339
|
});
|
|
340
|
-
return address
|
|
340
|
+
return address;
|
|
341
341
|
}
|
|
342
342
|
if (specifierIsPrefixOf(specifierCandidate, specifierNormalized)) {
|
|
343
343
|
const address = mappings[specifierCandidate];
|
|
@@ -352,18 +352,18 @@ const applyMappings = (
|
|
|
352
352
|
before: specifierNormalized,
|
|
353
353
|
after: addressFinal,
|
|
354
354
|
});
|
|
355
|
-
return addressFinal
|
|
355
|
+
return addressFinal;
|
|
356
356
|
}
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
return null
|
|
359
|
+
return null;
|
|
360
360
|
};
|
|
361
361
|
|
|
362
362
|
const specifierIsPrefixOf = (specifierHref, href) => {
|
|
363
363
|
return (
|
|
364
364
|
specifierHref[specifierHref.length - 1] === "/" &&
|
|
365
365
|
href.startsWith(specifierHref)
|
|
366
|
-
)
|
|
366
|
+
);
|
|
367
367
|
};
|
|
368
368
|
|
|
369
369
|
const sortImports = (imports) => {
|
|
@@ -375,7 +375,7 @@ const sortImports = (imports) => {
|
|
|
375
375
|
mappingsSorted[name] = imports[name];
|
|
376
376
|
});
|
|
377
377
|
|
|
378
|
-
return mappingsSorted
|
|
378
|
+
return mappingsSorted;
|
|
379
379
|
};
|
|
380
380
|
|
|
381
381
|
const sortScopes = (scopes) => {
|
|
@@ -387,18 +387,18 @@ const sortScopes = (scopes) => {
|
|
|
387
387
|
scopesSorted[scopeSpecifier] = sortImports(scopes[scopeSpecifier]);
|
|
388
388
|
});
|
|
389
389
|
|
|
390
|
-
return scopesSorted
|
|
390
|
+
return scopesSorted;
|
|
391
391
|
};
|
|
392
392
|
|
|
393
393
|
const compareLengthOrLocaleCompare = (a, b) => {
|
|
394
|
-
return b.length - a.length || a.localeCompare(b)
|
|
394
|
+
return b.length - a.length || a.localeCompare(b);
|
|
395
395
|
};
|
|
396
396
|
|
|
397
397
|
const normalizeImportMap = (importMap, baseUrl) => {
|
|
398
398
|
assertImportMap(importMap);
|
|
399
399
|
|
|
400
400
|
if (!isStringOrUrl(baseUrl)) {
|
|
401
|
-
throw new TypeError(formulateBaseUrlMustBeStringOrUrl({ baseUrl }))
|
|
401
|
+
throw new TypeError(formulateBaseUrlMustBeStringOrUrl({ baseUrl }));
|
|
402
402
|
}
|
|
403
403
|
|
|
404
404
|
const { imports, scopes } = importMap;
|
|
@@ -406,19 +406,19 @@ const normalizeImportMap = (importMap, baseUrl) => {
|
|
|
406
406
|
return {
|
|
407
407
|
imports: imports ? normalizeMappings(imports, baseUrl) : undefined,
|
|
408
408
|
scopes: scopes ? normalizeScopes(scopes, baseUrl) : undefined,
|
|
409
|
-
}
|
|
409
|
+
};
|
|
410
410
|
};
|
|
411
411
|
|
|
412
412
|
const isStringOrUrl = (value) => {
|
|
413
413
|
if (typeof value === "string") {
|
|
414
|
-
return true
|
|
414
|
+
return true;
|
|
415
415
|
}
|
|
416
416
|
|
|
417
417
|
if (typeof URL === "function" && value instanceof URL) {
|
|
418
|
-
return true
|
|
418
|
+
return true;
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
-
return false
|
|
421
|
+
return false;
|
|
422
422
|
};
|
|
423
423
|
|
|
424
424
|
const normalizeMappings = (mappings, baseUrl) => {
|
|
@@ -434,7 +434,7 @@ const normalizeMappings = (mappings, baseUrl) => {
|
|
|
434
434
|
specifier,
|
|
435
435
|
}),
|
|
436
436
|
);
|
|
437
|
-
return
|
|
437
|
+
return;
|
|
438
438
|
}
|
|
439
439
|
|
|
440
440
|
const specifierResolved = resolveSpecifier(specifier, baseUrl) || specifier;
|
|
@@ -448,7 +448,7 @@ const normalizeMappings = (mappings, baseUrl) => {
|
|
|
448
448
|
specifier,
|
|
449
449
|
}),
|
|
450
450
|
);
|
|
451
|
-
return
|
|
451
|
+
return;
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
if (specifier.endsWith("/") && !addressUrl.endsWith("/")) {
|
|
@@ -458,12 +458,12 @@ const normalizeMappings = (mappings, baseUrl) => {
|
|
|
458
458
|
specifier,
|
|
459
459
|
}),
|
|
460
460
|
);
|
|
461
|
-
return
|
|
461
|
+
return;
|
|
462
462
|
}
|
|
463
463
|
mappingsNormalized[specifierResolved] = addressUrl;
|
|
464
464
|
});
|
|
465
465
|
|
|
466
|
-
return sortImports(mappingsNormalized)
|
|
466
|
+
return sortImports(mappingsNormalized);
|
|
467
467
|
};
|
|
468
468
|
|
|
469
469
|
const normalizeScopes = (scopes, baseUrl) => {
|
|
@@ -479,13 +479,13 @@ const normalizeScopes = (scopes, baseUrl) => {
|
|
|
479
479
|
baseUrl,
|
|
480
480
|
}),
|
|
481
481
|
);
|
|
482
|
-
return
|
|
482
|
+
return;
|
|
483
483
|
}
|
|
484
484
|
const scopeValueNormalized = normalizeMappings(scopeMappings, baseUrl);
|
|
485
485
|
scopesNormalized[scopeUrl] = scopeValueNormalized;
|
|
486
486
|
});
|
|
487
487
|
|
|
488
|
-
return sortScopes(scopesNormalized)
|
|
488
|
+
return sortScopes(scopesNormalized);
|
|
489
489
|
};
|
|
490
490
|
|
|
491
491
|
const formulateBaseUrlMustBeStringOrUrl = ({
|
|
@@ -543,9 +543,9 @@ const pathnameToExtension = (pathname) => {
|
|
|
543
543
|
}
|
|
544
544
|
|
|
545
545
|
const dotLastIndex = pathname.lastIndexOf(".");
|
|
546
|
-
if (dotLastIndex === -1) return ""
|
|
546
|
+
if (dotLastIndex === -1) return "";
|
|
547
547
|
// if (dotLastIndex === pathname.length - 1) return ""
|
|
548
|
-
return pathname.slice(dotLastIndex)
|
|
548
|
+
return pathname.slice(dotLastIndex);
|
|
549
549
|
};
|
|
550
550
|
|
|
551
551
|
const resolveImport = ({
|
|
@@ -573,20 +573,20 @@ const resolveImport = ({
|
|
|
573
573
|
url = applyDefaultExtension({ url, importer, defaultExtension });
|
|
574
574
|
}
|
|
575
575
|
|
|
576
|
-
return url
|
|
576
|
+
return url;
|
|
577
577
|
};
|
|
578
578
|
|
|
579
579
|
const applyDefaultExtension = ({ url, importer, defaultExtension }) => {
|
|
580
580
|
if (urlToPathname(url).endsWith("/")) {
|
|
581
|
-
return url
|
|
581
|
+
return url;
|
|
582
582
|
}
|
|
583
583
|
|
|
584
584
|
if (typeof defaultExtension === "string") {
|
|
585
585
|
const extension = pathnameToExtension(url);
|
|
586
586
|
if (extension === "") {
|
|
587
|
-
return `${url}${defaultExtension}
|
|
587
|
+
return `${url}${defaultExtension}`;
|
|
588
588
|
}
|
|
589
|
-
return url
|
|
589
|
+
return url;
|
|
590
590
|
}
|
|
591
591
|
|
|
592
592
|
if (defaultExtension === true) {
|
|
@@ -594,11 +594,11 @@ const applyDefaultExtension = ({ url, importer, defaultExtension }) => {
|
|
|
594
594
|
if (extension === "" && importer) {
|
|
595
595
|
const importerPathname = urlToPathname(importer);
|
|
596
596
|
const importerExtension = pathnameToExtension(importerPathname);
|
|
597
|
-
return `${url}${importerExtension}
|
|
597
|
+
return `${url}${importerExtension}`;
|
|
598
598
|
}
|
|
599
599
|
}
|
|
600
600
|
|
|
601
|
-
return url
|
|
601
|
+
return url;
|
|
602
602
|
};
|
|
603
603
|
|
|
604
604
|
let importMap;
|
package/dist/jsenv_test.js
CHANGED
|
@@ -527,6 +527,60 @@ const SIGINT_CALLBACK = {
|
|
|
527
527
|
},
|
|
528
528
|
};
|
|
529
529
|
|
|
530
|
+
const isFileSystemPath = (value) => {
|
|
531
|
+
if (typeof value !== "string") {
|
|
532
|
+
throw new TypeError(
|
|
533
|
+
`isFileSystemPath first arg must be a string, got ${value}`,
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
if (value[0] === "/") {
|
|
537
|
+
return true;
|
|
538
|
+
}
|
|
539
|
+
return startsWithWindowsDriveLetter(value);
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
const startsWithWindowsDriveLetter = (string) => {
|
|
543
|
+
const firstChar = string[0];
|
|
544
|
+
if (!/[a-zA-Z]/.test(firstChar)) return false;
|
|
545
|
+
|
|
546
|
+
const secondChar = string[1];
|
|
547
|
+
if (secondChar !== ":") return false;
|
|
548
|
+
|
|
549
|
+
return true;
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
const fileSystemPathToUrl = (value) => {
|
|
553
|
+
if (!isFileSystemPath(value)) {
|
|
554
|
+
throw new Error(`value must be a filesystem path, got ${value}`);
|
|
555
|
+
}
|
|
556
|
+
return String(pathToFileURL(value));
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
const urlToFileSystemPath = (url) => {
|
|
560
|
+
const urlObject = new URL(url);
|
|
561
|
+
let { origin, pathname, hash } = urlObject;
|
|
562
|
+
if (urlObject.protocol === "file:") {
|
|
563
|
+
origin = "file://";
|
|
564
|
+
}
|
|
565
|
+
pathname = pathname
|
|
566
|
+
.split("/")
|
|
567
|
+
.map((part) => {
|
|
568
|
+
return part.replace(/%(?![0-9A-F][0-9A-F])/g, "%25");
|
|
569
|
+
})
|
|
570
|
+
.join("/");
|
|
571
|
+
if (hash) {
|
|
572
|
+
pathname += `%23${encodeURIComponent(hash.slice(1))}`;
|
|
573
|
+
}
|
|
574
|
+
const urlString = `${origin}${pathname}`;
|
|
575
|
+
const fileSystemPath = fileURLToPath(urlString);
|
|
576
|
+
if (fileSystemPath[fileSystemPath.length - 1] === "/") {
|
|
577
|
+
// remove trailing / so that nodejs path becomes predictable otherwise it logs
|
|
578
|
+
// the trailing slash on linux but does not on windows
|
|
579
|
+
return fileSystemPath.slice(0, -1);
|
|
580
|
+
}
|
|
581
|
+
return fileSystemPath;
|
|
582
|
+
};
|
|
583
|
+
|
|
530
584
|
const createDetailedMessage = (message, details = {}) => {
|
|
531
585
|
let text = `${message}`;
|
|
532
586
|
const namedSectionsText = renderNamedSections(details);
|
|
@@ -1706,42 +1760,6 @@ const ensurePathnameTrailingSlash = (url) => {
|
|
|
1706
1760
|
});
|
|
1707
1761
|
};
|
|
1708
1762
|
|
|
1709
|
-
const isFileSystemPath = (value) => {
|
|
1710
|
-
if (typeof value !== "string") {
|
|
1711
|
-
throw new TypeError(
|
|
1712
|
-
`isFileSystemPath first arg must be a string, got ${value}`,
|
|
1713
|
-
);
|
|
1714
|
-
}
|
|
1715
|
-
if (value[0] === "/") {
|
|
1716
|
-
return true;
|
|
1717
|
-
}
|
|
1718
|
-
return startsWithWindowsDriveLetter(value);
|
|
1719
|
-
};
|
|
1720
|
-
|
|
1721
|
-
const startsWithWindowsDriveLetter = (string) => {
|
|
1722
|
-
const firstChar = string[0];
|
|
1723
|
-
if (!/[a-zA-Z]/.test(firstChar)) return false;
|
|
1724
|
-
|
|
1725
|
-
const secondChar = string[1];
|
|
1726
|
-
if (secondChar !== ":") return false;
|
|
1727
|
-
|
|
1728
|
-
return true;
|
|
1729
|
-
};
|
|
1730
|
-
|
|
1731
|
-
const fileSystemPathToUrl = (value) => {
|
|
1732
|
-
if (!isFileSystemPath(value)) {
|
|
1733
|
-
throw new Error(`value must be a filesystem path, got ${value}`);
|
|
1734
|
-
}
|
|
1735
|
-
return String(pathToFileURL(value));
|
|
1736
|
-
};
|
|
1737
|
-
|
|
1738
|
-
const resolveUrl = (specifier, baseUrl) => {
|
|
1739
|
-
if (typeof baseUrl === "undefined") {
|
|
1740
|
-
throw new TypeError(`baseUrl missing to resolve ${specifier}`);
|
|
1741
|
-
}
|
|
1742
|
-
return String(new URL(specifier, baseUrl));
|
|
1743
|
-
};
|
|
1744
|
-
|
|
1745
1763
|
const getCommonPathname = (pathname, otherPathname) => {
|
|
1746
1764
|
if (pathname === otherPathname) {
|
|
1747
1765
|
return pathname;
|
|
@@ -1851,6 +1869,13 @@ const moveUrl = ({ url, from, to, preferRelative }) => {
|
|
|
1851
1869
|
return absoluteUrl;
|
|
1852
1870
|
};
|
|
1853
1871
|
|
|
1872
|
+
const resolveUrl = (specifier, baseUrl) => {
|
|
1873
|
+
if (typeof baseUrl === "undefined") {
|
|
1874
|
+
throw new TypeError(`baseUrl missing to resolve ${specifier}`);
|
|
1875
|
+
}
|
|
1876
|
+
return String(new URL(specifier, baseUrl));
|
|
1877
|
+
};
|
|
1878
|
+
|
|
1854
1879
|
const urlIsInsideOf = (url, otherUrl) => {
|
|
1855
1880
|
const urlObject = new URL(url);
|
|
1856
1881
|
const otherUrlObject = new URL(otherUrl);
|
|
@@ -1869,31 +1894,6 @@ const urlIsInsideOf = (url, otherUrl) => {
|
|
|
1869
1894
|
return isInside;
|
|
1870
1895
|
};
|
|
1871
1896
|
|
|
1872
|
-
const urlToFileSystemPath = (url) => {
|
|
1873
|
-
const urlObject = new URL(url);
|
|
1874
|
-
let { origin, pathname, hash } = urlObject;
|
|
1875
|
-
if (urlObject.protocol === "file:") {
|
|
1876
|
-
origin = "file://";
|
|
1877
|
-
}
|
|
1878
|
-
pathname = pathname
|
|
1879
|
-
.split("/")
|
|
1880
|
-
.map((part) => {
|
|
1881
|
-
return part.replace(/%(?![0-9A-F][0-9A-F])/g, "%25");
|
|
1882
|
-
})
|
|
1883
|
-
.join("/");
|
|
1884
|
-
if (hash) {
|
|
1885
|
-
pathname += `%23${encodeURIComponent(hash.slice(1))}`;
|
|
1886
|
-
}
|
|
1887
|
-
const urlString = `${origin}${pathname}`;
|
|
1888
|
-
const fileSystemPath = fileURLToPath(urlString);
|
|
1889
|
-
if (fileSystemPath[fileSystemPath.length - 1] === "/") {
|
|
1890
|
-
// remove trailing / so that nodejs path becomes predictable otherwise it logs
|
|
1891
|
-
// the trailing slash on linux but does not on windows
|
|
1892
|
-
return fileSystemPath.slice(0, -1);
|
|
1893
|
-
}
|
|
1894
|
-
return fileSystemPath;
|
|
1895
|
-
};
|
|
1896
|
-
|
|
1897
1897
|
const validateDirectoryUrl = (value) => {
|
|
1898
1898
|
let urlString;
|
|
1899
1899
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/test",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@c88/v8-coverage": "0.1.1",
|
|
48
|
-
"@jsenv/ast": "6.7.
|
|
49
|
-
"@jsenv/plugin-supervisor": "1.
|
|
50
|
-
"@jsenv/sourcemap": "1.3.
|
|
48
|
+
"@jsenv/ast": "6.7.2",
|
|
49
|
+
"@jsenv/plugin-supervisor": "1.7.0",
|
|
50
|
+
"@jsenv/sourcemap": "1.3.8",
|
|
51
51
|
"he": "1.2.0",
|
|
52
52
|
"istanbul-lib-coverage": "3.2.2",
|
|
53
53
|
"istanbul-lib-instrument": "6.0.3",
|
|
@@ -57,16 +57,26 @@
|
|
|
57
57
|
"v8-to-istanbul": "9.3.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@jsenv/
|
|
61
|
-
"@jsenv/
|
|
62
|
-
"@jsenv/
|
|
63
|
-
"@jsenv/
|
|
64
|
-
"@jsenv/
|
|
65
|
-
"@jsenv/
|
|
66
|
-
"@jsenv/
|
|
67
|
-
"@jsenv/
|
|
68
|
-
"@jsenv/
|
|
60
|
+
"@jsenv/assert": "../tooling/assert",
|
|
61
|
+
"@jsenv/snapshot": "../tooling/snapshot",
|
|
62
|
+
"@jsenv/terminal-recorder": "../tooling/terminal-recorder",
|
|
63
|
+
"@jsenv/server": "../backend/server",
|
|
64
|
+
"@jsenv/core": "../../",
|
|
65
|
+
"@jsenv/os-metrics": "../../tooling/os-metrics",
|
|
66
|
+
"@jsenv/importmap": "../../tooling/importmap",
|
|
67
|
+
"@jsenv/plugin-explorer": "../plugin-explorer",
|
|
68
|
+
"@jsenv/test": "./",
|
|
69
|
+
"@jsenv/abort": "../../tooling/abort",
|
|
70
|
+
"@jsenv/exception": "../../backend/exception",
|
|
71
|
+
"@jsenv/filesystem": "../../backend/filesystem",
|
|
72
|
+
"@jsenv/github-check-run": "../../tooling/github-check-run",
|
|
73
|
+
"@jsenv/node-esm-resolution": "../../tooling/node-esm-resolution",
|
|
74
|
+
"@jsenv/url-meta": "../../tooling/url-meta",
|
|
75
|
+
"@jsenv/urls": "../../tooling/urls",
|
|
76
|
+
"@jsenv/utils": "../../tooling/utils",
|
|
77
|
+
"@jsenv/humanize": "../../tooling/humanize",
|
|
69
78
|
"strip-ansi": "7.1.0",
|
|
70
|
-
"supports-color": "10.0.0"
|
|
79
|
+
"supports-color": "10.0.0",
|
|
80
|
+
"prettier": "3.5.3"
|
|
71
81
|
}
|
|
72
82
|
}
|