@jsenv/test 2.0.0 → 2.1.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.
package/dist/js/v8_coverage.js
CHANGED
|
@@ -39,6 +39,7 @@ const isWindowsPathnameSpecifier = (specifier) => {
|
|
|
39
39
|
const hasScheme = (specifier) => /^[a-zA-Z]+:/.test(specifier);
|
|
40
40
|
|
|
41
41
|
const resolveAssociations = (associations, baseUrl) => {
|
|
42
|
+
if (baseUrl && typeof baseUrl.href === "string") baseUrl = baseUrl.href;
|
|
42
43
|
assertUrlLike(baseUrl, "baseUrl");
|
|
43
44
|
const associationsResolved = {};
|
|
44
45
|
Object.keys(associations).forEach((key) => {
|
|
@@ -122,6 +123,7 @@ const asFlatAssociations = (associations) => {
|
|
|
122
123
|
*/
|
|
123
124
|
const applyPatternMatching = ({ url, pattern }) => {
|
|
124
125
|
assertUrlLike(pattern, "pattern");
|
|
126
|
+
if (url && typeof url.href === "string") url = url.href;
|
|
125
127
|
assertUrlLike(url, "url");
|
|
126
128
|
const { matched, patternIndex, index, groups } = applyMatching(pattern, url);
|
|
127
129
|
const matchGroups = [];
|
|
@@ -369,6 +371,7 @@ const skipUntilMatch = ({ pattern, string, canSkipSlash }) => {
|
|
|
369
371
|
};
|
|
370
372
|
|
|
371
373
|
const applyAssociations = ({ url, associations }) => {
|
|
374
|
+
if (url && typeof url.href === "string") url = url.href;
|
|
372
375
|
assertUrlLike(url);
|
|
373
376
|
const flatAssociations = asFlatAssociations(associations);
|
|
374
377
|
return Object.keys(flatAssociations).reduce((previousValue, pattern) => {
|
|
@@ -418,6 +421,7 @@ const applyAliases = ({ url, aliases }) => {
|
|
|
418
421
|
};
|
|
419
422
|
|
|
420
423
|
const urlChildMayMatch = ({ url, associations, predicate }) => {
|
|
424
|
+
if (url && typeof url.href === "string") url = url.href;
|
|
421
425
|
assertUrlLike(url, "url");
|
|
422
426
|
// the function was meants to be used on url ending with '/'
|
|
423
427
|
if (!url.endsWith("/")) {
|
package/dist/jsenv_test.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
|
-
import { chmod, stat, lstat,
|
|
2
|
+
import { readdir, chmod, stat, lstat, promises, readFile as readFile$1, writeFile as writeFile$1, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, readFileSync, readdirSync, existsSync } from "node:fs";
|
|
3
3
|
import process$1, { memoryUsage } from "node:process";
|
|
4
4
|
import v8, { takeCoverage } from "node:v8";
|
|
5
5
|
import stripAnsi from "strip-ansi";
|
|
6
6
|
import { URL_META, filterV8Coverage } from "./js/v8_coverage.js";
|
|
7
7
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
8
|
-
import crypto from "node:crypto";
|
|
9
8
|
import { dirname } from "node:path";
|
|
9
|
+
import crypto from "node:crypto";
|
|
10
10
|
import tty from "node:tty";
|
|
11
11
|
import stringWidth from "string-width";
|
|
12
12
|
import { readGitHubWorkflowEnv, startGithubCheckRun } from "@jsenv/github-check-run";
|
|
@@ -17,7 +17,7 @@ import { createServer } from "node:net";
|
|
|
17
17
|
import wrapAnsi from "wrap-ansi";
|
|
18
18
|
import { runInNewContext } from "node:vm";
|
|
19
19
|
import { injectSupervisorIntoHTML, supervisorFileUrl } from "@jsenv/plugin-supervisor";
|
|
20
|
-
import {
|
|
20
|
+
import { generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
|
|
21
21
|
import { findFreePort } from "@jsenv/server";
|
|
22
22
|
import { Worker } from "node:worker_threads";
|
|
23
23
|
|
|
@@ -865,15 +865,158 @@ const assertAndNormalizeFileUrl = (
|
|
|
865
865
|
return value;
|
|
866
866
|
};
|
|
867
867
|
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
868
|
+
const comparePathnames = (leftPathame, rightPathname) => {
|
|
869
|
+
const leftPartArray = leftPathame.split("/");
|
|
870
|
+
const rightPartArray = rightPathname.split("/");
|
|
871
|
+
|
|
872
|
+
const leftLength = leftPartArray.length;
|
|
873
|
+
const rightLength = rightPartArray.length;
|
|
874
|
+
|
|
875
|
+
const maxLength = Math.max(leftLength, rightLength);
|
|
876
|
+
let i = 0;
|
|
877
|
+
while (i < maxLength) {
|
|
878
|
+
const leftPartExists = i in leftPartArray;
|
|
879
|
+
const rightPartExists = i in rightPartArray;
|
|
880
|
+
|
|
881
|
+
// longer comes first
|
|
882
|
+
if (!leftPartExists) {
|
|
883
|
+
return +1;
|
|
884
|
+
}
|
|
885
|
+
if (!rightPartExists) {
|
|
886
|
+
return -1;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
const leftPartIsLast = i === leftPartArray.length - 1;
|
|
890
|
+
const rightPartIsLast = i === rightPartArray.length - 1;
|
|
891
|
+
// folder comes first
|
|
892
|
+
if (leftPartIsLast && !rightPartIsLast) {
|
|
893
|
+
return +1;
|
|
894
|
+
}
|
|
895
|
+
if (!leftPartIsLast && rightPartIsLast) {
|
|
896
|
+
return -1;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const leftPart = leftPartArray[i];
|
|
900
|
+
const rightPart = rightPartArray[i];
|
|
901
|
+
i++;
|
|
902
|
+
// local comparison comes first
|
|
903
|
+
const comparison = leftPart.localeCompare(rightPart);
|
|
904
|
+
if (comparison !== 0) {
|
|
905
|
+
return comparison;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (leftLength < rightLength) {
|
|
910
|
+
return +1;
|
|
911
|
+
}
|
|
912
|
+
if (leftLength > rightLength) {
|
|
913
|
+
return -1;
|
|
914
|
+
}
|
|
915
|
+
return 0;
|
|
916
|
+
};
|
|
917
|
+
|
|
918
|
+
const isWindows$2 = process.platform === "win32";
|
|
919
|
+
const baseUrlFallback = fileSystemPathToUrl(process.cwd());
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Some url might be resolved or remapped to url without the windows drive letter.
|
|
923
|
+
* For instance
|
|
924
|
+
* new URL('/foo.js', 'file:///C:/dir/file.js')
|
|
925
|
+
* resolves to
|
|
926
|
+
* 'file:///foo.js'
|
|
927
|
+
*
|
|
928
|
+
* But on windows it becomes a problem because we need the drive letter otherwise
|
|
929
|
+
* url cannot be converted to a filesystem path.
|
|
930
|
+
*
|
|
931
|
+
* ensureWindowsDriveLetter ensure a resolved url still contains the drive letter.
|
|
932
|
+
*/
|
|
933
|
+
|
|
934
|
+
const ensureWindowsDriveLetter = (url, baseUrl) => {
|
|
935
|
+
try {
|
|
936
|
+
url = String(new URL(url));
|
|
937
|
+
} catch (e) {
|
|
938
|
+
throw new Error(`absolute url expected but got ${url}`);
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
if (!isWindows$2) {
|
|
942
|
+
return url;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
try {
|
|
946
|
+
baseUrl = String(new URL(baseUrl));
|
|
947
|
+
} catch (e) {
|
|
948
|
+
throw new Error(
|
|
949
|
+
`absolute baseUrl expected but got ${baseUrl} to ensure windows drive letter on ${url}`,
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
if (!url.startsWith("file://")) {
|
|
954
|
+
return url;
|
|
955
|
+
}
|
|
956
|
+
const afterProtocol = url.slice("file://".length);
|
|
957
|
+
// we still have the windows drive letter
|
|
958
|
+
if (extractDriveLetter(afterProtocol)) {
|
|
959
|
+
return url;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// drive letter was lost, restore it
|
|
963
|
+
const baseUrlOrFallback = baseUrl.startsWith("file://")
|
|
964
|
+
? baseUrl
|
|
965
|
+
: baseUrlFallback;
|
|
966
|
+
const driveLetter = extractDriveLetter(
|
|
967
|
+
baseUrlOrFallback.slice("file://".length),
|
|
968
|
+
);
|
|
969
|
+
if (!driveLetter) {
|
|
970
|
+
throw new Error(
|
|
971
|
+
`drive letter expected on baseUrl but got ${baseUrl} to ensure windows drive letter on ${url}`,
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
return `file:///${driveLetter}:${afterProtocol}`;
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
const extractDriveLetter = (resource) => {
|
|
978
|
+
// we still have the windows drive letter
|
|
979
|
+
if (/[a-zA-Z]/.test(resource[1]) && resource[2] === ":") {
|
|
980
|
+
return resource[1];
|
|
981
|
+
}
|
|
982
|
+
return null;
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
const readDirectory = async (url, { emfileMaxWait = 1000 } = {}) => {
|
|
986
|
+
const directoryUrl = assertAndNormalizeDirectoryUrl(url);
|
|
987
|
+
const directoryUrlObject = new URL(directoryUrl);
|
|
988
|
+
const startMs = Date.now();
|
|
989
|
+
let attemptCount = 0;
|
|
990
|
+
|
|
991
|
+
const attempt = async () => {
|
|
992
|
+
try {
|
|
993
|
+
const names = await new Promise((resolve, reject) => {
|
|
994
|
+
readdir(directoryUrlObject, (error, names) => {
|
|
995
|
+
if (error) {
|
|
996
|
+
reject(error);
|
|
997
|
+
} else {
|
|
998
|
+
resolve(names);
|
|
999
|
+
}
|
|
1000
|
+
});
|
|
1001
|
+
});
|
|
1002
|
+
return names.map(encodeURIComponent);
|
|
1003
|
+
} catch (e) {
|
|
1004
|
+
// https://nodejs.org/dist/latest-v13.x/docs/api/errors.html#errors_common_system_errors
|
|
1005
|
+
if (e.code === "EMFILE" || e.code === "ENFILE") {
|
|
1006
|
+
attemptCount++;
|
|
1007
|
+
const nowMs = Date.now();
|
|
1008
|
+
const timeSpentWaiting = nowMs - startMs;
|
|
1009
|
+
if (timeSpentWaiting > emfileMaxWait) {
|
|
1010
|
+
throw e;
|
|
1011
|
+
}
|
|
1012
|
+
await new Promise((resolve) => setTimeout(resolve), attemptCount);
|
|
1013
|
+
return await attempt();
|
|
1014
|
+
}
|
|
1015
|
+
throw e;
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
return attempt();
|
|
877
1020
|
};
|
|
878
1021
|
|
|
879
1022
|
// https://github.com/coderaiser/cloudcmd/issues/63#issuecomment-195478143
|
|
@@ -996,7 +1139,7 @@ const getPermissionOrComputeDefault = (action, subject, permissions) => {
|
|
|
996
1139
|
*/
|
|
997
1140
|
|
|
998
1141
|
|
|
999
|
-
const isWindows$
|
|
1142
|
+
const isWindows$1 = process.platform === "win32";
|
|
1000
1143
|
|
|
1001
1144
|
const readEntryStat = async (
|
|
1002
1145
|
source,
|
|
@@ -1016,7 +1159,7 @@ const readEntryStat = async (
|
|
|
1016
1159
|
return readStat(sourcePath, {
|
|
1017
1160
|
followLink,
|
|
1018
1161
|
...handleNotFoundOption,
|
|
1019
|
-
...(isWindows$
|
|
1162
|
+
...(isWindows$1
|
|
1020
1163
|
? {
|
|
1021
1164
|
// Windows can EPERM on stat
|
|
1022
1165
|
handlePermissionDeniedError: async (error) => {
|
|
@@ -1081,93 +1224,6 @@ const readStat = (
|
|
|
1081
1224
|
});
|
|
1082
1225
|
};
|
|
1083
1226
|
|
|
1084
|
-
const readDirectory = async (url, { emfileMaxWait = 1000 } = {}) => {
|
|
1085
|
-
const directoryUrl = assertAndNormalizeDirectoryUrl(url);
|
|
1086
|
-
const directoryUrlObject = new URL(directoryUrl);
|
|
1087
|
-
const startMs = Date.now();
|
|
1088
|
-
let attemptCount = 0;
|
|
1089
|
-
|
|
1090
|
-
const attempt = async () => {
|
|
1091
|
-
try {
|
|
1092
|
-
const names = await new Promise((resolve, reject) => {
|
|
1093
|
-
readdir(directoryUrlObject, (error, names) => {
|
|
1094
|
-
if (error) {
|
|
1095
|
-
reject(error);
|
|
1096
|
-
} else {
|
|
1097
|
-
resolve(names);
|
|
1098
|
-
}
|
|
1099
|
-
});
|
|
1100
|
-
});
|
|
1101
|
-
return names.map(encodeURIComponent);
|
|
1102
|
-
} catch (e) {
|
|
1103
|
-
// https://nodejs.org/dist/latest-v13.x/docs/api/errors.html#errors_common_system_errors
|
|
1104
|
-
if (e.code === "EMFILE" || e.code === "ENFILE") {
|
|
1105
|
-
attemptCount++;
|
|
1106
|
-
const nowMs = Date.now();
|
|
1107
|
-
const timeSpentWaiting = nowMs - startMs;
|
|
1108
|
-
if (timeSpentWaiting > emfileMaxWait) {
|
|
1109
|
-
throw e;
|
|
1110
|
-
}
|
|
1111
|
-
await new Promise((resolve) => setTimeout(resolve), attemptCount);
|
|
1112
|
-
return await attempt();
|
|
1113
|
-
}
|
|
1114
|
-
throw e;
|
|
1115
|
-
}
|
|
1116
|
-
};
|
|
1117
|
-
|
|
1118
|
-
return attempt();
|
|
1119
|
-
};
|
|
1120
|
-
|
|
1121
|
-
const comparePathnames = (leftPathame, rightPathname) => {
|
|
1122
|
-
const leftPartArray = leftPathame.split("/");
|
|
1123
|
-
const rightPartArray = rightPathname.split("/");
|
|
1124
|
-
|
|
1125
|
-
const leftLength = leftPartArray.length;
|
|
1126
|
-
const rightLength = rightPartArray.length;
|
|
1127
|
-
|
|
1128
|
-
const maxLength = Math.max(leftLength, rightLength);
|
|
1129
|
-
let i = 0;
|
|
1130
|
-
while (i < maxLength) {
|
|
1131
|
-
const leftPartExists = i in leftPartArray;
|
|
1132
|
-
const rightPartExists = i in rightPartArray;
|
|
1133
|
-
|
|
1134
|
-
// longer comes first
|
|
1135
|
-
if (!leftPartExists) {
|
|
1136
|
-
return +1;
|
|
1137
|
-
}
|
|
1138
|
-
if (!rightPartExists) {
|
|
1139
|
-
return -1;
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
const leftPartIsLast = i === leftPartArray.length - 1;
|
|
1143
|
-
const rightPartIsLast = i === rightPartArray.length - 1;
|
|
1144
|
-
// folder comes first
|
|
1145
|
-
if (leftPartIsLast && !rightPartIsLast) {
|
|
1146
|
-
return +1;
|
|
1147
|
-
}
|
|
1148
|
-
if (!leftPartIsLast && rightPartIsLast) {
|
|
1149
|
-
return -1;
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
const leftPart = leftPartArray[i];
|
|
1153
|
-
const rightPart = rightPartArray[i];
|
|
1154
|
-
i++;
|
|
1155
|
-
// local comparison comes first
|
|
1156
|
-
const comparison = leftPart.localeCompare(rightPart);
|
|
1157
|
-
if (comparison !== 0) {
|
|
1158
|
-
return comparison;
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
if (leftLength < rightLength) {
|
|
1163
|
-
return +1;
|
|
1164
|
-
}
|
|
1165
|
-
if (leftLength > rightLength) {
|
|
1166
|
-
return -1;
|
|
1167
|
-
}
|
|
1168
|
-
return 0;
|
|
1169
|
-
};
|
|
1170
|
-
|
|
1171
1227
|
const collectFiles = async ({
|
|
1172
1228
|
signal = new AbortController().signal,
|
|
1173
1229
|
directoryUrl,
|
|
@@ -1259,6 +1315,17 @@ const collectFiles = async ({
|
|
|
1259
1315
|
}
|
|
1260
1316
|
};
|
|
1261
1317
|
|
|
1318
|
+
const statsToType = (stats) => {
|
|
1319
|
+
if (stats.isFile()) return "file";
|
|
1320
|
+
if (stats.isDirectory()) return "directory";
|
|
1321
|
+
if (stats.isSymbolicLink()) return "symbolic-link";
|
|
1322
|
+
if (stats.isFIFO()) return "fifo";
|
|
1323
|
+
if (stats.isSocket()) return "socket";
|
|
1324
|
+
if (stats.isCharacterDevice()) return "character-device";
|
|
1325
|
+
if (stats.isBlockDevice()) return "block-device";
|
|
1326
|
+
return undefined;
|
|
1327
|
+
};
|
|
1328
|
+
|
|
1262
1329
|
// https://nodejs.org/dist/latest-v13.x/docs/api/fs.html#fs_fspromises_mkdir_path_options
|
|
1263
1330
|
const { mkdir } = promises;
|
|
1264
1331
|
|
|
@@ -1298,6 +1365,86 @@ const writeDirectory = async (
|
|
|
1298
1365
|
}
|
|
1299
1366
|
};
|
|
1300
1367
|
|
|
1368
|
+
const ensureParentDirectories = async (destination) => {
|
|
1369
|
+
const destinationUrl = assertAndNormalizeFileUrl(destination);
|
|
1370
|
+
const destinationPath = urlToFileSystemPath(destinationUrl);
|
|
1371
|
+
const destinationParentPath = dirname(destinationPath);
|
|
1372
|
+
|
|
1373
|
+
await writeDirectory(destinationParentPath, {
|
|
1374
|
+
recursive: true,
|
|
1375
|
+
allowUseless: true,
|
|
1376
|
+
});
|
|
1377
|
+
};
|
|
1378
|
+
|
|
1379
|
+
const readFile = async (value, { as = "buffer" } = {}) => {
|
|
1380
|
+
const fileUrl = assertAndNormalizeFileUrl(value);
|
|
1381
|
+
const buffer = await new Promise((resolve, reject) => {
|
|
1382
|
+
readFile$1(new URL(fileUrl), (error, buffer) => {
|
|
1383
|
+
if (error) {
|
|
1384
|
+
reject(error);
|
|
1385
|
+
} else {
|
|
1386
|
+
resolve(buffer);
|
|
1387
|
+
}
|
|
1388
|
+
});
|
|
1389
|
+
});
|
|
1390
|
+
if (as === "buffer") {
|
|
1391
|
+
return buffer;
|
|
1392
|
+
}
|
|
1393
|
+
if (as === "string") {
|
|
1394
|
+
return buffer.toString();
|
|
1395
|
+
}
|
|
1396
|
+
if (as === "json") {
|
|
1397
|
+
return JSON.parse(buffer.toString());
|
|
1398
|
+
}
|
|
1399
|
+
throw new Error(
|
|
1400
|
+
`"as" must be one of "buffer","string","json" received "${as}"`,
|
|
1401
|
+
);
|
|
1402
|
+
};
|
|
1403
|
+
|
|
1404
|
+
const writeFile = async (destination, content = "") => {
|
|
1405
|
+
const destinationUrl = assertAndNormalizeFileUrl(destination);
|
|
1406
|
+
const destinationUrlObject = new URL(destinationUrl);
|
|
1407
|
+
try {
|
|
1408
|
+
await writeFileNaive(destinationUrlObject, content);
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
if (error.code === "ENOENT") {
|
|
1411
|
+
await ensureParentDirectories(destinationUrl);
|
|
1412
|
+
await writeFileNaive(destinationUrlObject, content);
|
|
1413
|
+
return;
|
|
1414
|
+
}
|
|
1415
|
+
throw error;
|
|
1416
|
+
}
|
|
1417
|
+
};
|
|
1418
|
+
|
|
1419
|
+
const writeFileNaive = (urlObject, content) => {
|
|
1420
|
+
return new Promise((resolve, reject) => {
|
|
1421
|
+
writeFile$1(urlObject, content, (error) => {
|
|
1422
|
+
if (error) {
|
|
1423
|
+
reject(error);
|
|
1424
|
+
} else {
|
|
1425
|
+
resolve();
|
|
1426
|
+
}
|
|
1427
|
+
});
|
|
1428
|
+
});
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1431
|
+
const writeFileSync = (destination, content = "") => {
|
|
1432
|
+
const destinationUrl = assertAndNormalizeFileUrl(destination);
|
|
1433
|
+
const destinationUrlObject = new URL(destinationUrl);
|
|
1434
|
+
try {
|
|
1435
|
+
writeFileSync$1(destinationUrlObject, content);
|
|
1436
|
+
} catch (error) {
|
|
1437
|
+
if (error.code === "ENOENT") {
|
|
1438
|
+
mkdirSync(new URL("./", destinationUrlObject), {
|
|
1439
|
+
recursive: true,
|
|
1440
|
+
});
|
|
1441
|
+
writeFileSync$1(destinationUrlObject, content);
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
throw error;
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1447
|
+
|
|
1301
1448
|
const removeEntry = async (
|
|
1302
1449
|
source,
|
|
1303
1450
|
{
|
|
@@ -1543,6 +1690,18 @@ const removeDirectoryNaive = (
|
|
|
1543
1690
|
});
|
|
1544
1691
|
};
|
|
1545
1692
|
|
|
1693
|
+
process.platform === "win32";
|
|
1694
|
+
|
|
1695
|
+
/*
|
|
1696
|
+
* - stats object documentation on Node.js
|
|
1697
|
+
* https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
|
|
1698
|
+
*/
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
process.platform === "win32";
|
|
1702
|
+
|
|
1703
|
+
process.platform === "win32";
|
|
1704
|
+
|
|
1546
1705
|
const ensureEmptyDirectory = async (source) => {
|
|
1547
1706
|
const stats = await readEntryStat(source, {
|
|
1548
1707
|
nullIfNotFound: true,
|
|
@@ -1550,15 +1709,17 @@ const ensureEmptyDirectory = async (source) => {
|
|
|
1550
1709
|
});
|
|
1551
1710
|
if (stats === null) {
|
|
1552
1711
|
// if there is nothing, create a directory
|
|
1553
|
-
|
|
1712
|
+
await writeDirectory(source, { allowUseless: true });
|
|
1713
|
+
return;
|
|
1554
1714
|
}
|
|
1555
1715
|
if (stats.isDirectory()) {
|
|
1556
1716
|
// if there is a directory remove its content and done
|
|
1557
|
-
|
|
1717
|
+
await removeEntry(source, {
|
|
1558
1718
|
allowUseless: true,
|
|
1559
1719
|
recursive: true,
|
|
1560
1720
|
onlyContent: true,
|
|
1561
1721
|
});
|
|
1722
|
+
return;
|
|
1562
1723
|
}
|
|
1563
1724
|
|
|
1564
1725
|
const sourceType = statsToType(stats);
|
|
@@ -1568,159 +1729,10 @@ const ensureEmptyDirectory = async (source) => {
|
|
|
1568
1729
|
);
|
|
1569
1730
|
};
|
|
1570
1731
|
|
|
1571
|
-
const ensureParentDirectories = async (destination) => {
|
|
1572
|
-
const destinationUrl = assertAndNormalizeFileUrl(destination);
|
|
1573
|
-
const destinationPath = urlToFileSystemPath(destinationUrl);
|
|
1574
|
-
const destinationParentPath = dirname(destinationPath);
|
|
1575
|
-
|
|
1576
|
-
return writeDirectory(destinationParentPath, {
|
|
1577
|
-
recursive: true,
|
|
1578
|
-
allowUseless: true,
|
|
1579
|
-
});
|
|
1580
|
-
};
|
|
1581
|
-
|
|
1582
|
-
const isWindows$1 = process.platform === "win32";
|
|
1583
|
-
const baseUrlFallback = fileSystemPathToUrl(process.cwd());
|
|
1584
|
-
|
|
1585
|
-
/**
|
|
1586
|
-
* Some url might be resolved or remapped to url without the windows drive letter.
|
|
1587
|
-
* For instance
|
|
1588
|
-
* new URL('/foo.js', 'file:///C:/dir/file.js')
|
|
1589
|
-
* resolves to
|
|
1590
|
-
* 'file:///foo.js'
|
|
1591
|
-
*
|
|
1592
|
-
* But on windows it becomes a problem because we need the drive letter otherwise
|
|
1593
|
-
* url cannot be converted to a filesystem path.
|
|
1594
|
-
*
|
|
1595
|
-
* ensureWindowsDriveLetter ensure a resolved url still contains the drive letter.
|
|
1596
|
-
*/
|
|
1597
|
-
|
|
1598
|
-
const ensureWindowsDriveLetter = (url, baseUrl) => {
|
|
1599
|
-
try {
|
|
1600
|
-
url = String(new URL(url));
|
|
1601
|
-
} catch (e) {
|
|
1602
|
-
throw new Error(`absolute url expected but got ${url}`);
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
|
-
if (!isWindows$1) {
|
|
1606
|
-
return url;
|
|
1607
|
-
}
|
|
1608
|
-
|
|
1609
|
-
try {
|
|
1610
|
-
baseUrl = String(new URL(baseUrl));
|
|
1611
|
-
} catch (e) {
|
|
1612
|
-
throw new Error(
|
|
1613
|
-
`absolute baseUrl expected but got ${baseUrl} to ensure windows drive letter on ${url}`,
|
|
1614
|
-
);
|
|
1615
|
-
}
|
|
1616
|
-
|
|
1617
|
-
if (!url.startsWith("file://")) {
|
|
1618
|
-
return url;
|
|
1619
|
-
}
|
|
1620
|
-
const afterProtocol = url.slice("file://".length);
|
|
1621
|
-
// we still have the windows drive letter
|
|
1622
|
-
if (extractDriveLetter(afterProtocol)) {
|
|
1623
|
-
return url;
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
// drive letter was lost, restore it
|
|
1627
|
-
const baseUrlOrFallback = baseUrl.startsWith("file://")
|
|
1628
|
-
? baseUrl
|
|
1629
|
-
: baseUrlFallback;
|
|
1630
|
-
const driveLetter = extractDriveLetter(
|
|
1631
|
-
baseUrlOrFallback.slice("file://".length),
|
|
1632
|
-
);
|
|
1633
|
-
if (!driveLetter) {
|
|
1634
|
-
throw new Error(
|
|
1635
|
-
`drive letter expected on baseUrl but got ${baseUrl} to ensure windows drive letter on ${url}`,
|
|
1636
|
-
);
|
|
1637
|
-
}
|
|
1638
|
-
return `file:///${driveLetter}:${afterProtocol}`;
|
|
1639
|
-
};
|
|
1640
|
-
|
|
1641
|
-
const extractDriveLetter = (resource) => {
|
|
1642
|
-
// we still have the windows drive letter
|
|
1643
|
-
if (/[a-zA-Z]/.test(resource[1]) && resource[2] === ":") {
|
|
1644
|
-
return resource[1];
|
|
1645
|
-
}
|
|
1646
|
-
return null;
|
|
1647
|
-
};
|
|
1648
|
-
|
|
1649
|
-
process.platform === "win32";
|
|
1650
|
-
|
|
1651
|
-
const readFile = async (value, { as = "buffer" } = {}) => {
|
|
1652
|
-
const fileUrl = assertAndNormalizeFileUrl(value);
|
|
1653
|
-
const buffer = await new Promise((resolve, reject) => {
|
|
1654
|
-
readFile$1(new URL(fileUrl), (error, buffer) => {
|
|
1655
|
-
if (error) {
|
|
1656
|
-
reject(error);
|
|
1657
|
-
} else {
|
|
1658
|
-
resolve(buffer);
|
|
1659
|
-
}
|
|
1660
|
-
});
|
|
1661
|
-
});
|
|
1662
|
-
if (as === "buffer") {
|
|
1663
|
-
return buffer;
|
|
1664
|
-
}
|
|
1665
|
-
if (as === "string") {
|
|
1666
|
-
return buffer.toString();
|
|
1667
|
-
}
|
|
1668
|
-
if (as === "json") {
|
|
1669
|
-
return JSON.parse(buffer.toString());
|
|
1670
|
-
}
|
|
1671
|
-
throw new Error(
|
|
1672
|
-
`"as" must be one of "buffer","string","json" received "${as}"`,
|
|
1673
|
-
);
|
|
1674
|
-
};
|
|
1675
|
-
|
|
1676
1732
|
process.platform === "win32";
|
|
1677
1733
|
|
|
1678
1734
|
process.platform === "linux";
|
|
1679
1735
|
|
|
1680
|
-
const writeFile = async (destination, content = "") => {
|
|
1681
|
-
const destinationUrl = assertAndNormalizeFileUrl(destination);
|
|
1682
|
-
const destinationUrlObject = new URL(destinationUrl);
|
|
1683
|
-
try {
|
|
1684
|
-
await writeFileNaive(destinationUrlObject, content);
|
|
1685
|
-
} catch (error) {
|
|
1686
|
-
if (error.code === "ENOENT") {
|
|
1687
|
-
await ensureParentDirectories(destinationUrl);
|
|
1688
|
-
await writeFileNaive(destinationUrlObject, content);
|
|
1689
|
-
return;
|
|
1690
|
-
}
|
|
1691
|
-
throw error;
|
|
1692
|
-
}
|
|
1693
|
-
};
|
|
1694
|
-
|
|
1695
|
-
const writeFileNaive = (urlObject, content) => {
|
|
1696
|
-
return new Promise((resolve, reject) => {
|
|
1697
|
-
writeFile$1(urlObject, content, (error) => {
|
|
1698
|
-
if (error) {
|
|
1699
|
-
reject(error);
|
|
1700
|
-
} else {
|
|
1701
|
-
resolve();
|
|
1702
|
-
}
|
|
1703
|
-
});
|
|
1704
|
-
});
|
|
1705
|
-
};
|
|
1706
|
-
|
|
1707
|
-
const writeFileSync = (destination, content = "") => {
|
|
1708
|
-
const destinationUrl = assertAndNormalizeFileUrl(destination);
|
|
1709
|
-
const destinationUrlObject = new URL(destinationUrl);
|
|
1710
|
-
try {
|
|
1711
|
-
writeFileSync$1(destinationUrlObject, content);
|
|
1712
|
-
} catch (error) {
|
|
1713
|
-
if (error.code === "ENOENT") {
|
|
1714
|
-
mkdirSync(new URL("./", destinationUrlObject), {
|
|
1715
|
-
recursive: true,
|
|
1716
|
-
});
|
|
1717
|
-
writeFileSync$1(destinationUrlObject, content);
|
|
1718
|
-
return;
|
|
1719
|
-
}
|
|
1720
|
-
throw error;
|
|
1721
|
-
}
|
|
1722
|
-
};
|
|
1723
|
-
|
|
1724
1736
|
const LOG_LEVEL_OFF = "off";
|
|
1725
1737
|
|
|
1726
1738
|
const LOG_LEVEL_DEBUG = "debug";
|
|
@@ -6880,9 +6892,12 @@ const nodeChildProcess = ({
|
|
|
6880
6892
|
);
|
|
6881
6893
|
return;
|
|
6882
6894
|
}
|
|
6895
|
+
if (code === null || code === 0) {
|
|
6896
|
+
result.status = "completed";
|
|
6897
|
+
result.namespace = {};
|
|
6898
|
+
return;
|
|
6899
|
+
}
|
|
6883
6900
|
if (
|
|
6884
|
-
code === null ||
|
|
6885
|
-
code === 0 ||
|
|
6886
6901
|
code === EXIT_CODES.SIGINT ||
|
|
6887
6902
|
code === EXIT_CODES.SIGTERM ||
|
|
6888
6903
|
code === EXIT_CODES.SIGABORT
|
|
@@ -7186,9 +7201,12 @@ const nodeWorkerThread = ({
|
|
|
7186
7201
|
);
|
|
7187
7202
|
return;
|
|
7188
7203
|
}
|
|
7204
|
+
if (code === null || code === 0) {
|
|
7205
|
+
result.status = "completed";
|
|
7206
|
+
result.namespace = {};
|
|
7207
|
+
return;
|
|
7208
|
+
}
|
|
7189
7209
|
if (
|
|
7190
|
-
code === null ||
|
|
7191
|
-
code === 0 ||
|
|
7192
7210
|
code === EXIT_CODES.SIGINT ||
|
|
7193
7211
|
code === EXIT_CODES.SIGTERM ||
|
|
7194
7212
|
code === EXIT_CODES.SIGABORT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/test",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@jsenv/abort": "4.2.4",
|
|
37
37
|
"@jsenv/ast": "6.0.1",
|
|
38
|
-
"@jsenv/filesystem": "4.
|
|
38
|
+
"@jsenv/filesystem": "4.5.0",
|
|
39
39
|
"@jsenv/log": "3.4.3",
|
|
40
|
-
"@jsenv/plugin-supervisor": "1.
|
|
40
|
+
"@jsenv/plugin-supervisor": "1.4.0",
|
|
41
41
|
"@jsenv/urls": "2.2.1",
|
|
42
|
-
"@jsenv/url-meta": "8.
|
|
42
|
+
"@jsenv/url-meta": "8.2.0",
|
|
43
43
|
"@jsenv/utils": "2.0.1",
|
|
44
|
-
"@jsenv/github-check-run": "0.1.
|
|
44
|
+
"@jsenv/github-check-run": "0.1.5",
|
|
45
45
|
"v8-to-istanbul": "9.1.3",
|
|
46
46
|
"istanbul-lib-coverage": "3.2.2",
|
|
47
47
|
"istanbul-lib-instrument": "6.0.1",
|
|
@@ -256,9 +256,12 @@ export const nodeChildProcess = ({
|
|
|
256
256
|
);
|
|
257
257
|
return;
|
|
258
258
|
}
|
|
259
|
+
if (code === null || code === 0) {
|
|
260
|
+
result.status = "completed";
|
|
261
|
+
result.namespace = {};
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
259
264
|
if (
|
|
260
|
-
code === null ||
|
|
261
|
-
code === 0 ||
|
|
262
265
|
code === EXIT_CODES.SIGINT ||
|
|
263
266
|
code === EXIT_CODES.SIGTERM ||
|
|
264
267
|
code === EXIT_CODES.SIGABORT
|
|
@@ -202,9 +202,12 @@ export const nodeWorkerThread = ({
|
|
|
202
202
|
);
|
|
203
203
|
return;
|
|
204
204
|
}
|
|
205
|
+
if (code === null || code === 0) {
|
|
206
|
+
result.status = "completed";
|
|
207
|
+
result.namespace = {};
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
205
210
|
if (
|
|
206
|
-
code === null ||
|
|
207
|
-
code === 0 ||
|
|
208
211
|
code === EXIT_CODES.SIGINT ||
|
|
209
212
|
code === EXIT_CODES.SIGTERM ||
|
|
210
213
|
code === EXIT_CODES.SIGABORT
|