@jsenv/test 3.5.31 → 3.5.33

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.
Files changed (2) hide show
  1. package/dist/jsenv_test.js +353 -252
  2. package/package.json +5 -5
@@ -4,7 +4,7 @@ import tty from "node:tty";
4
4
  import stringWidth from "string-width";
5
5
  import { pathToFileURL, fileURLToPath } from "node:url";
6
6
  import { URL_META, filterV8Coverage } from "./js/v8_coverage.js";
7
- import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFile as readFile$1, readFileSync, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, unlinkSync, readdirSync, rmdirSync, existsSync } from "node:fs";
7
+ import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFile as readFile$1, unlinkSync, openSync, closeSync, readdirSync, rmdirSync, mkdirSync, readFileSync, writeFileSync as writeFileSync$1, unlink, rmdir, existsSync } from "node:fs";
8
8
  import { dirname } from "node:path";
9
9
  import crypto from "node:crypto";
10
10
  import { readGitHubWorkflowEnv, startGithubCheckRun } from "@jsenv/github-check-run";
@@ -578,17 +578,29 @@ if (
578
578
  }
579
579
 
580
580
  function envForceColor() {
581
- if ('FORCE_COLOR' in env) {
582
- if (env.FORCE_COLOR === 'true') {
583
- return 1;
584
- }
581
+ if (!('FORCE_COLOR' in env)) {
582
+ return;
583
+ }
585
584
 
586
- if (env.FORCE_COLOR === 'false') {
587
- return 0;
588
- }
585
+ if (env.FORCE_COLOR === 'true') {
586
+ return 1;
587
+ }
588
+
589
+ if (env.FORCE_COLOR === 'false') {
590
+ return 0;
591
+ }
592
+
593
+ if (env.FORCE_COLOR.length === 0) {
594
+ return 1;
595
+ }
589
596
 
590
- return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
597
+ const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
598
+
599
+ if (![0, 1, 2, 3].includes(level)) {
600
+ return;
591
601
  }
602
+
603
+ return level;
592
604
  }
593
605
 
594
606
  function translateLevel(level) {
@@ -659,11 +671,11 @@ function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
659
671
  }
660
672
 
661
673
  if ('CI' in env) {
662
- if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
674
+ if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {
663
675
  return 3;
664
676
  }
665
677
 
666
- if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
678
+ if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
667
679
  return 1;
668
680
  }
669
681
 
@@ -2120,6 +2132,42 @@ const extractDriveLetter = (resource) => {
2120
2132
  return null;
2121
2133
  };
2122
2134
 
2135
+ const getParentDirectoryUrl = (url) => {
2136
+ if (url.startsWith("file://")) {
2137
+ // With node.js new URL('../', 'file:///C:/').href
2138
+ // returns "file:///C:/" instead of "file:///"
2139
+ const resource = url.slice("file://".length);
2140
+ const slashLastIndex = resource.lastIndexOf("/");
2141
+ if (slashLastIndex === -1) {
2142
+ return url;
2143
+ }
2144
+ const lastCharIndex = resource.length - 1;
2145
+ if (slashLastIndex === lastCharIndex) {
2146
+ const slashBeforeLastIndex = resource.lastIndexOf(
2147
+ "/",
2148
+ slashLastIndex - 1,
2149
+ );
2150
+ if (slashBeforeLastIndex === -1) {
2151
+ return url;
2152
+ }
2153
+ return `file://${resource.slice(0, slashBeforeLastIndex + 1)}`;
2154
+ }
2155
+ return `file://${resource.slice(0, slashLastIndex + 1)}`;
2156
+ }
2157
+ return new URL(url.endsWith("/") ? "../" : "./", url).href;
2158
+ };
2159
+
2160
+ const findAncestorDirectoryUrl = (url, callback) => {
2161
+ url = String(url);
2162
+ while (url !== "file:///") {
2163
+ if (callback(url)) {
2164
+ return url;
2165
+ }
2166
+ url = getParentDirectoryUrl(url);
2167
+ }
2168
+ return null;
2169
+ };
2170
+
2123
2171
  const readDirectory = async (url, { emfileMaxWait = 1000 } = {}) => {
2124
2172
  const directoryUrl = assertAndNormalizeDirectoryUrl(url);
2125
2173
  const directoryUrlObject = new URL(directoryUrl);
@@ -2542,7 +2590,284 @@ const readFile = async (value, { as = "buffer" } = {}) => {
2542
2590
  );
2543
2591
  };
2544
2592
 
2545
- const writeFileSync = (destination, content = "") => {
2593
+ const removeEntrySync = (
2594
+ source,
2595
+ {
2596
+ allowUseless = false,
2597
+ recursive = false,
2598
+ maxRetries = 3,
2599
+ retryDelay = 100,
2600
+ onlyContent = false,
2601
+ } = {},
2602
+ ) => {
2603
+ const sourceUrl = assertAndNormalizeFileUrl(source);
2604
+ const sourceStats = readEntryStatSync(sourceUrl, {
2605
+ nullIfNotFound: true,
2606
+ followLink: false,
2607
+ });
2608
+ if (!sourceStats) {
2609
+ if (allowUseless) {
2610
+ return;
2611
+ }
2612
+ throw new Error(`nothing to remove at ${urlToFileSystemPath(sourceUrl)}`);
2613
+ }
2614
+
2615
+ // https://nodejs.org/dist/latest-v13.x/docs/api/fs.html#fs_class_fs_stats
2616
+ // FIFO and socket are ignored, not sure what they are exactly and what to do with them
2617
+ // other libraries ignore them, let's do the same.
2618
+ if (
2619
+ sourceStats.isFile() ||
2620
+ sourceStats.isSymbolicLink() ||
2621
+ sourceStats.isCharacterDevice() ||
2622
+ sourceStats.isBlockDevice()
2623
+ ) {
2624
+ removeNonDirectory$1(
2625
+ sourceUrl.endsWith("/") ? sourceUrl.slice(0, -1) : sourceUrl);
2626
+ } else if (sourceStats.isDirectory()) {
2627
+ const directoryUrl = ensurePathnameTrailingSlash(sourceUrl);
2628
+ removeDirectorySync$1(directoryUrl, {
2629
+ recursive,
2630
+ maxRetries,
2631
+ retryDelay,
2632
+ onlyContent,
2633
+ });
2634
+ }
2635
+ };
2636
+
2637
+ const removeNonDirectory$1 = (sourceUrl) => {
2638
+ const sourcePath = urlToFileSystemPath(sourceUrl);
2639
+ const attempt = () => {
2640
+ unlinkSyncNaive(sourcePath);
2641
+ };
2642
+ attempt();
2643
+ };
2644
+
2645
+ const unlinkSyncNaive = (sourcePath, { handleTemporaryError = null } = {}) => {
2646
+ try {
2647
+ unlinkSync(sourcePath);
2648
+ } catch (error) {
2649
+ if (error.code === "ENOENT") {
2650
+ return;
2651
+ }
2652
+ if (
2653
+ handleTemporaryError &&
2654
+ (error.code === "EBUSY" ||
2655
+ error.code === "EMFILE" ||
2656
+ error.code === "ENFILE" ||
2657
+ error.code === "ENOENT")
2658
+ ) {
2659
+ handleTemporaryError(error);
2660
+ return;
2661
+ }
2662
+ throw error;
2663
+ }
2664
+ };
2665
+
2666
+ const removeDirectorySync$1 = (
2667
+ rootDirectoryUrl,
2668
+ { maxRetries, retryDelay, recursive, onlyContent },
2669
+ ) => {
2670
+ const visit = (sourceUrl) => {
2671
+ const sourceStats = readEntryStatSync(sourceUrl, {
2672
+ nullIfNotFound: true,
2673
+ followLink: false,
2674
+ });
2675
+
2676
+ // file/directory not found
2677
+ if (sourceStats === null) {
2678
+ return;
2679
+ }
2680
+
2681
+ if (
2682
+ sourceStats.isFile() ||
2683
+ sourceStats.isCharacterDevice() ||
2684
+ sourceStats.isBlockDevice()
2685
+ ) {
2686
+ visitFile(sourceUrl);
2687
+ } else if (sourceStats.isSymbolicLink()) {
2688
+ visitSymbolicLink(sourceUrl);
2689
+ } else if (sourceStats.isDirectory()) {
2690
+ visitDirectory(`${sourceUrl}/`);
2691
+ }
2692
+ };
2693
+
2694
+ const visitDirectory = (directoryUrl) => {
2695
+ const directoryPath = urlToFileSystemPath(directoryUrl);
2696
+ const optionsFromRecursive = recursive
2697
+ ? {
2698
+ handleNotEmptyError: () => {
2699
+ removeDirectoryContent(directoryUrl);
2700
+ visitDirectory(directoryUrl);
2701
+ },
2702
+ }
2703
+ : {};
2704
+ removeDirectorySyncNaive(directoryPath, {
2705
+ ...optionsFromRecursive,
2706
+ // Workaround for https://github.com/joyent/node/issues/4337
2707
+ ...(process.platform === "win32"
2708
+ ? {
2709
+ handlePermissionError: (error) => {
2710
+ console.error(
2711
+ `trying to fix windows EPERM after readir on ${directoryPath}`,
2712
+ );
2713
+
2714
+ let openOrCloseError;
2715
+ try {
2716
+ const fd = openSync(directoryPath);
2717
+ closeSync(fd);
2718
+ } catch (e) {
2719
+ openOrCloseError = e;
2720
+ }
2721
+
2722
+ if (openOrCloseError) {
2723
+ if (openOrCloseError.code === "ENOENT") {
2724
+ return;
2725
+ }
2726
+ console.error(
2727
+ `error while trying to fix windows EPERM after readir on ${directoryPath}: ${openOrCloseError.stack}`,
2728
+ );
2729
+ throw error;
2730
+ }
2731
+ removeDirectorySyncNaive(directoryPath, {
2732
+ ...optionsFromRecursive,
2733
+ });
2734
+ },
2735
+ }
2736
+ : {}),
2737
+ });
2738
+ };
2739
+
2740
+ const removeDirectoryContent = (directoryUrl) => {
2741
+ const entryNames = readdirSync(new URL(directoryUrl));
2742
+ for (const entryName of entryNames) {
2743
+ const url = resolveUrl(entryName, directoryUrl);
2744
+ visit(url);
2745
+ }
2746
+ };
2747
+
2748
+ const visitFile = (fileUrl) => {
2749
+ removeNonDirectory$1(fileUrl);
2750
+ };
2751
+
2752
+ const visitSymbolicLink = (symbolicLinkUrl) => {
2753
+ removeNonDirectory$1(symbolicLinkUrl);
2754
+ };
2755
+
2756
+ if (onlyContent) {
2757
+ removeDirectoryContent(rootDirectoryUrl);
2758
+ } else {
2759
+ visitDirectory(rootDirectoryUrl);
2760
+ }
2761
+ };
2762
+
2763
+ const removeDirectorySyncNaive = (
2764
+ directoryPath,
2765
+ { handleNotEmptyError = null, handlePermissionError = null } = {},
2766
+ ) => {
2767
+ try {
2768
+ rmdirSync(directoryPath);
2769
+ } catch (error) {
2770
+ if (handlePermissionError && error.code === "EPERM") {
2771
+ handlePermissionError(error);
2772
+ return;
2773
+ }
2774
+ if (error.code === "ENOENT") {
2775
+ return;
2776
+ }
2777
+ if (
2778
+ handleNotEmptyError &&
2779
+ // linux os
2780
+ (error.code === "ENOTEMPTY" ||
2781
+ // SunOS
2782
+ error.code === "EEXIST")
2783
+ ) {
2784
+ handleNotEmptyError(error);
2785
+ return;
2786
+ }
2787
+ throw error;
2788
+ }
2789
+ };
2790
+
2791
+ const removeDirectorySync = (url, options = {}) => {
2792
+ return removeEntrySync(url, {
2793
+ ...options,
2794
+ recursive: true,
2795
+ });
2796
+ };
2797
+
2798
+ const writeDirectorySync = (
2799
+ destination,
2800
+ { recursive = true, allowUseless = false, force } = {},
2801
+ ) => {
2802
+ const destinationUrl = assertAndNormalizeDirectoryUrl(destination);
2803
+ const destinationPath = urlToFileSystemPath(destinationUrl);
2804
+
2805
+ let destinationStats;
2806
+ try {
2807
+ destinationStats = readEntryStatSync(destinationUrl, {
2808
+ nullIfNotFound: true,
2809
+ followLink: false,
2810
+ });
2811
+ } catch (e) {
2812
+ if (e.code === "ENOTDIR") {
2813
+ let previousNonDirUrl = destinationUrl;
2814
+ // we must try all parent directories as long as it fails with ENOTDIR
2815
+ findAncestorDirectoryUrl(destinationUrl, (ancestorUrl) => {
2816
+ try {
2817
+ statSync(new URL(ancestorUrl));
2818
+ return true;
2819
+ } catch (e) {
2820
+ if (e.code === "ENOTDIR") {
2821
+ previousNonDirUrl = ancestorUrl;
2822
+ return false;
2823
+ }
2824
+ throw e;
2825
+ }
2826
+ });
2827
+ if (force) {
2828
+ unlinkSync(
2829
+ new URL(
2830
+ previousNonDirUrl
2831
+ // remove trailing slash
2832
+ .slice(0, -1),
2833
+ ),
2834
+ );
2835
+ } else {
2836
+ throw new Error(
2837
+ `cannot write directory at ${destinationPath} because there is a file at ${urlToFileSystemPath(
2838
+ previousNonDirUrl,
2839
+ )}`,
2840
+ );
2841
+ }
2842
+ } else {
2843
+ throw e;
2844
+ }
2845
+ }
2846
+
2847
+ if (destinationStats) {
2848
+ if (destinationStats.isDirectory()) {
2849
+ if (allowUseless) {
2850
+ return;
2851
+ }
2852
+ throw new Error(`directory already exists at ${destinationPath}`);
2853
+ }
2854
+ const destinationType = statsToType(destinationStats);
2855
+ throw new Error(
2856
+ `cannot write directory at ${destinationPath} because there is a ${destinationType}`,
2857
+ );
2858
+ }
2859
+
2860
+ try {
2861
+ mkdirSync(destinationPath, { recursive });
2862
+ } catch (error) {
2863
+ if (allowUseless && error.code === "EEXIST") {
2864
+ return;
2865
+ }
2866
+ throw error;
2867
+ }
2868
+ };
2869
+
2870
+ const writeFileSync = (destination, content = "", { force } = {}) => {
2546
2871
  const destinationUrl = assertAndNormalizeFileUrl(destination);
2547
2872
  const destinationUrlObject = new URL(destinationUrl);
2548
2873
  if (content && content instanceof URL) {
@@ -2551,8 +2876,18 @@ const writeFileSync = (destination, content = "") => {
2551
2876
  try {
2552
2877
  writeFileSync$1(destinationUrlObject, content);
2553
2878
  } catch (error) {
2554
- if (error.code === "ENOENT") {
2555
- mkdirSync(new URL("./", destinationUrlObject), {
2879
+ if (error.code === "EISDIR") {
2880
+ // happens when directory existed but got deleted and now it's a file
2881
+ if (force) {
2882
+ removeDirectorySync(destinationUrlObject);
2883
+ writeFileSync$1(destinationUrlObject, content);
2884
+ } else {
2885
+ throw error;
2886
+ }
2887
+ }
2888
+ if (error.code === "ENOENT" || error.code === "ENOTDIR") {
2889
+ writeDirectorySync(new URL("./", destinationUrlObject), {
2890
+ force,
2556
2891
  recursive: true,
2557
2892
  });
2558
2893
  writeFileSync$1(destinationUrlObject, content);
@@ -2600,7 +2935,7 @@ const removeEntry = async (
2600
2935
  sourceStats.isCharacterDevice() ||
2601
2936
  sourceStats.isBlockDevice()
2602
2937
  ) {
2603
- await removeNonDirectory$1(
2938
+ await removeNonDirectory(
2604
2939
  sourceUrl.endsWith("/") ? sourceUrl.slice(0, -1) : sourceUrl,
2605
2940
  {
2606
2941
  maxRetries,
@@ -2621,7 +2956,7 @@ const removeEntry = async (
2621
2956
  }
2622
2957
  };
2623
2958
 
2624
- const removeNonDirectory$1 = (sourceUrl, { maxRetries, retryDelay }) => {
2959
+ const removeNonDirectory = (sourceUrl, { maxRetries, retryDelay }) => {
2625
2960
  const sourcePath = urlToFileSystemPath(sourceUrl);
2626
2961
 
2627
2962
  let retryCount = 0;
@@ -2760,11 +3095,11 @@ const removeDirectory = async (
2760
3095
  };
2761
3096
 
2762
3097
  const visitFile = async (fileUrl) => {
2763
- await removeNonDirectory$1(fileUrl, { maxRetries, retryDelay });
3098
+ await removeNonDirectory(fileUrl, { maxRetries, retryDelay });
2764
3099
  };
2765
3100
 
2766
3101
  const visitSymbolicLink = async (symbolicLinkUrl) => {
2767
- await removeNonDirectory$1(symbolicLinkUrl, { maxRetries, retryDelay });
3102
+ await removeNonDirectory(symbolicLinkUrl, { maxRetries, retryDelay });
2768
3103
  };
2769
3104
 
2770
3105
  try {
@@ -2809,240 +3144,6 @@ const removeDirectoryNaive = (
2809
3144
 
2810
3145
  process.platform === "win32";
2811
3146
 
2812
- const writeDirectorySync = (
2813
- destination,
2814
- { recursive = true, allowUseless = false } = {},
2815
- ) => {
2816
- const destinationUrl = assertAndNormalizeDirectoryUrl(destination);
2817
- const destinationPath = urlToFileSystemPath(destinationUrl);
2818
-
2819
- const destinationStats = readEntryStatSync(destinationUrl, {
2820
- nullIfNotFound: true,
2821
- followLink: false,
2822
- });
2823
-
2824
- if (destinationStats) {
2825
- if (destinationStats.isDirectory()) {
2826
- if (allowUseless) {
2827
- return;
2828
- }
2829
- throw new Error(`directory already exists at ${destinationPath}`);
2830
- }
2831
-
2832
- const destinationType = statsToType(destinationStats);
2833
- throw new Error(
2834
- `cannot write directory at ${destinationPath} because there is a ${destinationType}`,
2835
- );
2836
- }
2837
-
2838
- try {
2839
- mkdirSync(destinationPath, { recursive });
2840
- } catch (error) {
2841
- if (allowUseless && error.code === "EEXIST") {
2842
- return;
2843
- }
2844
- throw error;
2845
- }
2846
- };
2847
-
2848
- const removeEntrySync = (
2849
- source,
2850
- {
2851
- allowUseless = false,
2852
- recursive = false,
2853
- maxRetries = 3,
2854
- retryDelay = 100,
2855
- onlyContent = false,
2856
- } = {},
2857
- ) => {
2858
- const sourceUrl = assertAndNormalizeFileUrl(source);
2859
- const sourceStats = readEntryStatSync(sourceUrl, {
2860
- nullIfNotFound: true,
2861
- followLink: false,
2862
- });
2863
- if (!sourceStats) {
2864
- if (allowUseless) {
2865
- return;
2866
- }
2867
- throw new Error(`nothing to remove at ${urlToFileSystemPath(sourceUrl)}`);
2868
- }
2869
-
2870
- // https://nodejs.org/dist/latest-v13.x/docs/api/fs.html#fs_class_fs_stats
2871
- // FIFO and socket are ignored, not sure what they are exactly and what to do with them
2872
- // other libraries ignore them, let's do the same.
2873
- if (
2874
- sourceStats.isFile() ||
2875
- sourceStats.isSymbolicLink() ||
2876
- sourceStats.isCharacterDevice() ||
2877
- sourceStats.isBlockDevice()
2878
- ) {
2879
- removeNonDirectory(
2880
- sourceUrl.endsWith("/") ? sourceUrl.slice(0, -1) : sourceUrl);
2881
- } else if (sourceStats.isDirectory()) {
2882
- const directoryUrl = ensurePathnameTrailingSlash(sourceUrl);
2883
- removeDirectorySync(directoryUrl, {
2884
- recursive,
2885
- maxRetries,
2886
- retryDelay,
2887
- onlyContent,
2888
- });
2889
- }
2890
- };
2891
-
2892
- const removeNonDirectory = (sourceUrl) => {
2893
- const sourcePath = urlToFileSystemPath(sourceUrl);
2894
- const attempt = () => {
2895
- unlinkSyncNaive(sourcePath);
2896
- };
2897
- attempt();
2898
- };
2899
-
2900
- const unlinkSyncNaive = (sourcePath, { handleTemporaryError = null } = {}) => {
2901
- try {
2902
- unlinkSync(sourcePath);
2903
- } catch (error) {
2904
- if (error.code === "ENOENT") {
2905
- return;
2906
- }
2907
- if (
2908
- handleTemporaryError &&
2909
- (error.code === "EBUSY" ||
2910
- error.code === "EMFILE" ||
2911
- error.code === "ENFILE" ||
2912
- error.code === "ENOENT")
2913
- ) {
2914
- handleTemporaryError(error);
2915
- return;
2916
- }
2917
- throw error;
2918
- }
2919
- };
2920
-
2921
- const removeDirectorySync = (
2922
- rootDirectoryUrl,
2923
- { maxRetries, retryDelay, recursive, onlyContent },
2924
- ) => {
2925
- const visit = (sourceUrl) => {
2926
- const sourceStats = readEntryStatSync(sourceUrl, {
2927
- nullIfNotFound: true,
2928
- followLink: false,
2929
- });
2930
-
2931
- // file/directory not found
2932
- if (sourceStats === null) {
2933
- return;
2934
- }
2935
-
2936
- if (
2937
- sourceStats.isFile() ||
2938
- sourceStats.isCharacterDevice() ||
2939
- sourceStats.isBlockDevice()
2940
- ) {
2941
- visitFile(sourceUrl);
2942
- } else if (sourceStats.isSymbolicLink()) {
2943
- visitSymbolicLink(sourceUrl);
2944
- } else if (sourceStats.isDirectory()) {
2945
- visitDirectory(`${sourceUrl}/`);
2946
- }
2947
- };
2948
-
2949
- const visitDirectory = (directoryUrl) => {
2950
- const directoryPath = urlToFileSystemPath(directoryUrl);
2951
- const optionsFromRecursive = recursive
2952
- ? {
2953
- handleNotEmptyError: () => {
2954
- removeDirectoryContent(directoryUrl);
2955
- visitDirectory(directoryUrl);
2956
- },
2957
- }
2958
- : {};
2959
- removeDirectorySyncNaive(directoryPath, {
2960
- ...optionsFromRecursive,
2961
- // Workaround for https://github.com/joyent/node/issues/4337
2962
- ...(process.platform === "win32"
2963
- ? {
2964
- handlePermissionError: (error) => {
2965
- console.error(
2966
- `trying to fix windows EPERM after readir on ${directoryPath}`,
2967
- );
2968
-
2969
- let openOrCloseError;
2970
- try {
2971
- const fd = openSync(directoryPath);
2972
- closeSync(fd);
2973
- } catch (e) {
2974
- openOrCloseError = e;
2975
- }
2976
-
2977
- if (openOrCloseError) {
2978
- if (openOrCloseError.code === "ENOENT") {
2979
- return;
2980
- }
2981
- console.error(
2982
- `error while trying to fix windows EPERM after readir on ${directoryPath}: ${openOrCloseError.stack}`,
2983
- );
2984
- throw error;
2985
- }
2986
- removeDirectorySyncNaive(directoryPath, {
2987
- ...optionsFromRecursive,
2988
- });
2989
- },
2990
- }
2991
- : {}),
2992
- });
2993
- };
2994
-
2995
- const removeDirectoryContent = (directoryUrl) => {
2996
- const entryNames = readdirSync(new URL(directoryUrl));
2997
- for (const entryName of entryNames) {
2998
- const url = resolveUrl(entryName, directoryUrl);
2999
- visit(url);
3000
- }
3001
- };
3002
-
3003
- const visitFile = (fileUrl) => {
3004
- removeNonDirectory(fileUrl);
3005
- };
3006
-
3007
- const visitSymbolicLink = (symbolicLinkUrl) => {
3008
- removeNonDirectory(symbolicLinkUrl);
3009
- };
3010
-
3011
- if (onlyContent) {
3012
- removeDirectoryContent(rootDirectoryUrl);
3013
- } else {
3014
- visitDirectory(rootDirectoryUrl);
3015
- }
3016
- };
3017
-
3018
- const removeDirectorySyncNaive = (
3019
- directoryPath,
3020
- { handleNotEmptyError = null, handlePermissionError = null } = {},
3021
- ) => {
3022
- try {
3023
- rmdirSync(directoryPath);
3024
- } catch (error) {
3025
- if (handlePermissionError && error.code === "EPERM") {
3026
- handlePermissionError(error);
3027
- return;
3028
- }
3029
- if (error.code === "ENOENT") {
3030
- return;
3031
- }
3032
- if (
3033
- handleNotEmptyError &&
3034
- // linux os
3035
- (error.code === "ENOTEMPTY" ||
3036
- // SunOS
3037
- error.code === "EEXIST")
3038
- ) {
3039
- handleNotEmptyError(error);
3040
- return;
3041
- }
3042
- throw error;
3043
- }
3044
- };
3045
-
3046
3147
  process.platform === "win32";
3047
3148
 
3048
3149
  const ensureEmptyDirectorySync = (source) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/test",
3
- "version": "3.5.31",
3
+ "version": "3.5.33",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,12 +39,12 @@
39
39
  "@jsenv/abort": "4.3.0",
40
40
  "@jsenv/ast": "6.4.1",
41
41
  "@jsenv/exception": "1.1.3",
42
- "@jsenv/filesystem": "4.11.0",
42
+ "@jsenv/filesystem": "4.12.0",
43
43
  "@jsenv/github-check-run": "0.2.5",
44
44
  "@jsenv/node-esm-resolution": "1.0.6",
45
45
  "@jsenv/humanize": "1.2.8",
46
- "@jsenv/plugin-supervisor": "1.6.0",
47
- "@jsenv/sourcemap": "1.2.28",
46
+ "@jsenv/plugin-supervisor": "1.6.1",
47
+ "@jsenv/sourcemap": "1.2.29",
48
48
  "@jsenv/url-meta": "8.5.2",
49
49
  "@jsenv/urls": "2.5.4",
50
50
  "@jsenv/utils": "2.1.2",
@@ -55,7 +55,7 @@
55
55
  "istanbul-reports": "3.1.7",
56
56
  "pidtree": "0.6.0",
57
57
  "strip-ansi": "7.1.0",
58
- "supports-color": "9.4.0",
58
+ "supports-color": "10.0.0",
59
59
  "v8-to-istanbul": "9.3.0"
60
60
  }
61
61
  }