@goodbyenjn/utils 26.4.0 → 26.4.2

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/fs.js CHANGED
@@ -1,15 +1,15 @@
1
- import { i as __toESM, t as __commonJSMin } from "./chunks/chunk-7ffde8d4.js";
2
- import { Gt as isString, Tt as isArray, pn as omit, zt as isNumber } from "./chunks/chunk-b61db0a7.js";
3
- import { A as Result, D as safeParse, M as ok, O as stringify, j as err, l as removePrefix } from "./chunks/chunk-486f65b0.js";
4
- import * as nativeFs$1 from "fs";
5
- import nativeFs from "fs";
6
- import path, { basename, dirname, normalize, posix, relative, resolve, sep } from "path";
1
+ import { a as __toESM, t as __commonJSMin } from "./chunks/chunk-3ce2ea14.js";
2
+ import { $t as isArray, C as isNil, Si as err, Vn as omit, l as removePrefix, pn as isNumber, w as nil$2, wi as ok, xi as Result, yn as isString } from "./chunks/chunk-11b9216b.js";
3
+ import { i as stringify, n as stringify$1, r as parse, t as parse$1 } from "./chunks/chunk-1b381080.js";
4
+ import path, { dirname } from "node:path";
5
+ import { basename, dirname as dirname$1, isAbsolute, normalize, posix, relative, resolve, sep } from "path";
6
+ import * as nativeFs from "fs";
7
+ import { readdir, readdirSync, realpath, realpathSync, stat, statSync } from "fs";
7
8
  import { fileURLToPath } from "url";
8
9
  import { createRequire } from "module";
10
+ import url from "node:url";
9
11
  import fs, { promises } from "node:fs";
10
- import path$1, { dirname as dirname$1 } from "node:path";
11
-
12
- //#region node_modules/.pnpm/fdir@6.5.0_picomatch@4.0.3/node_modules/fdir/dist/index.mjs
12
+ //#region node_modules/.pnpm/fdir@6.5.0_picomatch@4.0.4/node_modules/fdir/dist/index.mjs
13
13
  var __require = createRequire(import.meta.url);
14
14
  function cleanPath(path) {
15
15
  let normalized = normalize(path);
@@ -147,12 +147,12 @@ function build$2(options, isSynchronous) {
147
147
  }
148
148
  function isRecursive(path, resolved, state) {
149
149
  if (state.options.useRealPaths) return isRecursiveUsingRealPaths(resolved, state);
150
- let parent = dirname(path);
150
+ let parent = dirname$1(path);
151
151
  let depth = 1;
152
152
  while (parent !== state.root && depth < 2) {
153
153
  const resolvedPath = state.symlinks.get(parent);
154
154
  if (!!resolvedPath && (resolvedPath === resolved || resolvedPath.startsWith(resolved) || resolved.startsWith(resolvedPath))) depth++;
155
- else parent = dirname(parent);
155
+ else parent = dirname$1(parent);
156
156
  }
157
157
  state.symlinks.set(path, resolved);
158
158
  return depth > 1;
@@ -297,7 +297,7 @@ var Walker = class {
297
297
  symlinks: new Map(),
298
298
  visited: [""].slice(0, 0),
299
299
  controller: new Aborter(),
300
- fs: options.fs || nativeFs$1
300
+ fs: options.fs || nativeFs
301
301
  };
302
302
  this.joinPath = build$7(this.root, options);
303
303
  this.pushDirectory = build$6(this.root, options);
@@ -336,7 +336,7 @@ var Walker = class {
336
336
  } else {
337
337
  resolvedPath = useRealPaths ? resolvedPath : path;
338
338
  const filename = basename(resolvedPath);
339
- const directoryPath$1 = normalizePath(dirname(resolvedPath), this.state.options);
339
+ const directoryPath$1 = normalizePath(dirname$1(resolvedPath), this.state.options);
340
340
  resolvedPath = this.joinPath(filename, directoryPath$1);
341
341
  this.pushFile(resolvedPath, files, this.state.counts, filters);
342
342
  }
@@ -493,12 +493,12 @@ var Builder = class {
493
493
  return this;
494
494
  }
495
495
  };
496
-
497
496
  //#endregion
498
- //#region node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/constants.js
497
+ //#region node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/constants.js
499
498
  var require_constants = __commonJSMin(((exports, module) => {
500
499
  const WIN_SLASH = "\\\\/";
501
500
  const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
501
+ const DEFAULT_MAX_EXTGLOB_RECURSION = 0;
502
502
  const DOT_LITERAL = "\\.";
503
503
  const PLUS_LITERAL = "\\+";
504
504
  const QMARK_LITERAL = "\\?";
@@ -541,25 +541,26 @@ var require_constants = __commonJSMin(((exports, module) => {
541
541
  END_ANCHOR: `(?:[${WIN_SLASH}]|$)`,
542
542
  SEP: "\\"
543
543
  };
544
- const POSIX_REGEX_SOURCE = {
545
- alnum: "a-zA-Z0-9",
546
- alpha: "a-zA-Z",
547
- ascii: "\\x00-\\x7F",
548
- blank: " \\t",
549
- cntrl: "\\x00-\\x1F\\x7F",
550
- digit: "0-9",
551
- graph: "\\x21-\\x7E",
552
- lower: "a-z",
553
- print: "\\x20-\\x7E ",
554
- punct: "\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",
555
- space: " \\t\\r\\n\\v\\f",
556
- upper: "A-Z",
557
- word: "A-Za-z0-9_",
558
- xdigit: "A-Fa-f0-9"
559
- };
560
544
  module.exports = {
545
+ DEFAULT_MAX_EXTGLOB_RECURSION,
561
546
  MAX_LENGTH: 1024 * 64,
562
- POSIX_REGEX_SOURCE,
547
+ POSIX_REGEX_SOURCE: {
548
+ __proto__: null,
549
+ alnum: "a-zA-Z0-9",
550
+ alpha: "a-zA-Z",
551
+ ascii: "\\x00-\\x7F",
552
+ blank: " \\t",
553
+ cntrl: "\\x00-\\x1F\\x7F",
554
+ digit: "0-9",
555
+ graph: "\\x21-\\x7E",
556
+ lower: "a-z",
557
+ print: "\\x20-\\x7E ",
558
+ punct: "\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",
559
+ space: " \\t\\r\\n\\v\\f",
560
+ upper: "A-Z",
561
+ word: "A-Za-z0-9_",
562
+ xdigit: "A-Fa-f0-9"
563
+ },
563
564
  REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
564
565
  REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
565
566
  REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
@@ -649,9 +650,8 @@ var require_constants = __commonJSMin(((exports, module) => {
649
650
  }
650
651
  };
651
652
  }));
652
-
653
653
  //#endregion
654
- //#region node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/utils.js
654
+ //#region node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/utils.js
655
655
  var require_utils = __commonJSMin(((exports) => {
656
656
  const { REGEX_BACKSLASH, REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL } = require_constants();
657
657
  exports.isObject = (val) => val !== null && typeof val === "object" && !Array.isArray(val);
@@ -698,9 +698,8 @@ var require_utils = __commonJSMin(((exports) => {
698
698
  return last;
699
699
  };
700
700
  }));
701
-
702
701
  //#endregion
703
- //#region node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/scan.js
702
+ //#region node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/scan.js
704
703
  var require_scan = __commonJSMin(((exports, module) => {
705
704
  const utils = require_utils();
706
705
  const { CHAR_ASTERISK, CHAR_AT, CHAR_BACKWARD_SLASH, CHAR_COMMA, CHAR_DOT, CHAR_EXCLAMATION_MARK, CHAR_FORWARD_SLASH, CHAR_LEFT_CURLY_BRACE, CHAR_LEFT_PARENTHESES, CHAR_LEFT_SQUARE_BRACKET, CHAR_PLUS, CHAR_QUESTION_MARK, CHAR_RIGHT_CURLY_BRACE, CHAR_RIGHT_PARENTHESES, CHAR_RIGHT_SQUARE_BRACKET } = require_constants();
@@ -970,9 +969,8 @@ var require_scan = __commonJSMin(((exports, module) => {
970
969
  };
971
970
  module.exports = scan;
972
971
  }));
973
-
974
972
  //#endregion
975
- //#region node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/parse.js
973
+ //#region node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/parse.js
976
974
  var require_parse = __commonJSMin(((exports, module) => {
977
975
  const constants = require_constants();
978
976
  const utils = require_utils();
@@ -991,6 +989,177 @@ var require_parse = __commonJSMin(((exports, module) => {
991
989
  const syntaxError = (type, char) => {
992
990
  return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
993
991
  };
992
+ const splitTopLevel = (input) => {
993
+ const parts = [];
994
+ let bracket = 0;
995
+ let paren = 0;
996
+ let quote = 0;
997
+ let value = "";
998
+ let escaped = false;
999
+ for (const ch of input) {
1000
+ if (escaped === true) {
1001
+ value += ch;
1002
+ escaped = false;
1003
+ continue;
1004
+ }
1005
+ if (ch === "\\") {
1006
+ value += ch;
1007
+ escaped = true;
1008
+ continue;
1009
+ }
1010
+ if (ch === "\"") {
1011
+ quote = quote === 1 ? 0 : 1;
1012
+ value += ch;
1013
+ continue;
1014
+ }
1015
+ if (quote === 0) {
1016
+ if (ch === "[") bracket++;
1017
+ else if (ch === "]" && bracket > 0) bracket--;
1018
+ else if (bracket === 0) {
1019
+ if (ch === "(") paren++;
1020
+ else if (ch === ")" && paren > 0) paren--;
1021
+ else if (ch === "|" && paren === 0) {
1022
+ parts.push(value);
1023
+ value = "";
1024
+ continue;
1025
+ }
1026
+ }
1027
+ }
1028
+ value += ch;
1029
+ }
1030
+ parts.push(value);
1031
+ return parts;
1032
+ };
1033
+ const isPlainBranch = (branch) => {
1034
+ let escaped = false;
1035
+ for (const ch of branch) {
1036
+ if (escaped === true) {
1037
+ escaped = false;
1038
+ continue;
1039
+ }
1040
+ if (ch === "\\") {
1041
+ escaped = true;
1042
+ continue;
1043
+ }
1044
+ if (/[?*+@!()[\]{}]/.test(ch)) return false;
1045
+ }
1046
+ return true;
1047
+ };
1048
+ const normalizeSimpleBranch = (branch) => {
1049
+ let value = branch.trim();
1050
+ let changed = true;
1051
+ while (changed === true) {
1052
+ changed = false;
1053
+ if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
1054
+ value = value.slice(2, -1);
1055
+ changed = true;
1056
+ }
1057
+ }
1058
+ if (!isPlainBranch(value)) return;
1059
+ return value.replace(/\\(.)/g, "$1");
1060
+ };
1061
+ const hasRepeatedCharPrefixOverlap = (branches) => {
1062
+ const values = branches.map(normalizeSimpleBranch).filter(Boolean);
1063
+ for (let i = 0; i < values.length; i++) for (let j = i + 1; j < values.length; j++) {
1064
+ const a = values[i];
1065
+ const b = values[j];
1066
+ const char = a[0];
1067
+ if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) continue;
1068
+ if (a === b || a.startsWith(b) || b.startsWith(a)) return true;
1069
+ }
1070
+ return false;
1071
+ };
1072
+ const parseRepeatedExtglob = (pattern, requireEnd = true) => {
1073
+ if (pattern[0] !== "+" && pattern[0] !== "*" || pattern[1] !== "(") return;
1074
+ let bracket = 0;
1075
+ let paren = 0;
1076
+ let quote = 0;
1077
+ let escaped = false;
1078
+ for (let i = 1; i < pattern.length; i++) {
1079
+ const ch = pattern[i];
1080
+ if (escaped === true) {
1081
+ escaped = false;
1082
+ continue;
1083
+ }
1084
+ if (ch === "\\") {
1085
+ escaped = true;
1086
+ continue;
1087
+ }
1088
+ if (ch === "\"") {
1089
+ quote = quote === 1 ? 0 : 1;
1090
+ continue;
1091
+ }
1092
+ if (quote === 1) continue;
1093
+ if (ch === "[") {
1094
+ bracket++;
1095
+ continue;
1096
+ }
1097
+ if (ch === "]" && bracket > 0) {
1098
+ bracket--;
1099
+ continue;
1100
+ }
1101
+ if (bracket > 0) continue;
1102
+ if (ch === "(") {
1103
+ paren++;
1104
+ continue;
1105
+ }
1106
+ if (ch === ")") {
1107
+ paren--;
1108
+ if (paren === 0) {
1109
+ if (requireEnd === true && i !== pattern.length - 1) return;
1110
+ return {
1111
+ type: pattern[0],
1112
+ body: pattern.slice(2, i),
1113
+ end: i
1114
+ };
1115
+ }
1116
+ }
1117
+ }
1118
+ };
1119
+ const getStarExtglobSequenceOutput = (pattern) => {
1120
+ let index = 0;
1121
+ const chars = [];
1122
+ while (index < pattern.length) {
1123
+ const match = parseRepeatedExtglob(pattern.slice(index), false);
1124
+ if (!match || match.type !== "*") return;
1125
+ const branches = splitTopLevel(match.body).map((branch) => branch.trim());
1126
+ if (branches.length !== 1) return;
1127
+ const branch = normalizeSimpleBranch(branches[0]);
1128
+ if (!branch || branch.length !== 1) return;
1129
+ chars.push(branch);
1130
+ index += match.end + 1;
1131
+ }
1132
+ if (chars.length < 1) return;
1133
+ return `${chars.length === 1 ? utils.escapeRegex(chars[0]) : `[${chars.map((ch) => utils.escapeRegex(ch)).join("")}]`}*`;
1134
+ };
1135
+ const repeatedExtglobRecursion = (pattern) => {
1136
+ let depth = 0;
1137
+ let value = pattern.trim();
1138
+ let match = parseRepeatedExtglob(value);
1139
+ while (match) {
1140
+ depth++;
1141
+ value = match.body.trim();
1142
+ match = parseRepeatedExtglob(value);
1143
+ }
1144
+ return depth;
1145
+ };
1146
+ const analyzeRepeatedExtglob = (body, options) => {
1147
+ if (options.maxExtglobRecursion === false) return { risky: false };
1148
+ const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants.DEFAULT_MAX_EXTGLOB_RECURSION;
1149
+ const branches = splitTopLevel(body).map((branch) => branch.trim());
1150
+ if (branches.length > 1) {
1151
+ if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) return { risky: true };
1152
+ }
1153
+ for (const branch of branches) {
1154
+ const safeOutput = getStarExtglobSequenceOutput(branch);
1155
+ if (safeOutput) return {
1156
+ risky: true,
1157
+ safeOutput
1158
+ };
1159
+ if (repeatedExtglobRecursion(branch) > max) return { risky: true };
1160
+ }
1161
+ return { risky: false };
1162
+ };
994
1163
  const parse = (input, options) => {
995
1164
  if (typeof input !== "string") throw new TypeError("Expected a string");
996
1165
  input = REPLACEMENTS[input] || input;
@@ -1104,6 +1273,8 @@ var require_parse = __commonJSMin(((exports, module) => {
1104
1273
  token.prev = prev;
1105
1274
  token.parens = state.parens;
1106
1275
  token.output = state.output;
1276
+ token.startIndex = state.index;
1277
+ token.tokensIndex = tokens.length;
1107
1278
  const output = (opts.capture ? "(" : "") + token.open;
1108
1279
  increment("parens");
1109
1280
  push({
@@ -1120,6 +1291,30 @@ var require_parse = __commonJSMin(((exports, module) => {
1120
1291
  extglobs.push(token);
1121
1292
  };
1122
1293
  const extglobClose = (token) => {
1294
+ const literal = input.slice(token.startIndex, state.index + 1);
1295
+ const analysis = analyzeRepeatedExtglob(input.slice(token.startIndex + 2, state.index), opts);
1296
+ if ((token.type === "plus" || token.type === "star") && analysis.risky) {
1297
+ const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
1298
+ const open = tokens[token.tokensIndex];
1299
+ open.type = "text";
1300
+ open.value = literal;
1301
+ open.output = safeOutput || utils.escapeRegex(literal);
1302
+ for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
1303
+ tokens[i].value = "";
1304
+ tokens[i].output = "";
1305
+ delete tokens[i].suffix;
1306
+ }
1307
+ state.output = token.output + open.output;
1308
+ state.backtrack = true;
1309
+ push({
1310
+ type: "paren",
1311
+ extglob: true,
1312
+ value,
1313
+ output: ""
1314
+ });
1315
+ decrement("parens");
1316
+ return;
1317
+ }
1123
1318
  let output = token.close + (opts.capture ? ")" : "");
1124
1319
  let rest;
1125
1320
  if (token.type === "negate") {
@@ -1740,9 +1935,8 @@ var require_parse = __commonJSMin(((exports, module) => {
1740
1935
  };
1741
1936
  module.exports = parse;
1742
1937
  }));
1743
-
1744
1938
  //#endregion
1745
- //#region node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/picomatch.js
1939
+ //#region node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/picomatch.js
1746
1940
  var require_picomatch$1 = __commonJSMin(((exports, module) => {
1747
1941
  const scan = require_scan();
1748
1942
  const parse = require_parse();
@@ -1876,10 +2070,9 @@ var require_picomatch$1 = __commonJSMin(((exports, module) => {
1876
2070
  picomatch.constants = constants;
1877
2071
  module.exports = picomatch;
1878
2072
  }));
1879
-
1880
2073
  //#endregion
1881
- //#region node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/index.js
1882
- var require_picomatch = __commonJSMin(((exports, module) => {
2074
+ //#region node_modules/.pnpm/tinyglobby@0.2.16/node_modules/tinyglobby/dist/index.mjs
2075
+ var import_picomatch = __toESM(__commonJSMin(((exports, module) => {
1883
2076
  const pico = require_picomatch$1();
1884
2077
  const utils = require_utils();
1885
2078
  function picomatch(glob, options, returnState = false) {
@@ -1891,41 +2084,38 @@ var require_picomatch = __commonJSMin(((exports, module) => {
1891
2084
  }
1892
2085
  Object.assign(picomatch, pico);
1893
2086
  module.exports = picomatch;
1894
- }));
1895
-
1896
- //#endregion
1897
- //#region node_modules/.pnpm/tinyglobby@0.2.15/node_modules/tinyglobby/dist/index.mjs
1898
- var import_picomatch = __toESM(require_picomatch(), 1);
2087
+ }))(), 1);
1899
2088
  const isReadonlyArray = Array.isArray;
2089
+ const BACKSLASHES = /\\/g;
1900
2090
  const isWin = process.platform === "win32";
1901
2091
  const ONLY_PARENT_DIRECTORIES = /^(\/?\.\.)+$/;
1902
2092
  function getPartialMatcher(patterns, options = {}) {
1903
2093
  const patternsCount = patterns.length;
1904
2094
  const patternsParts = Array(patternsCount);
1905
2095
  const matchers = Array(patternsCount);
1906
- const globstarEnabled = !options.noglobstar;
1907
- for (let i = 0; i < patternsCount; i++) {
2096
+ let i, j;
2097
+ for (i = 0; i < patternsCount; i++) {
1908
2098
  const parts = splitPattern(patterns[i]);
1909
2099
  patternsParts[i] = parts;
1910
2100
  const partsCount = parts.length;
1911
2101
  const partMatchers = Array(partsCount);
1912
- for (let j = 0; j < partsCount; j++) partMatchers[j] = (0, import_picomatch.default)(parts[j], options);
2102
+ for (j = 0; j < partsCount; j++) partMatchers[j] = (0, import_picomatch.default)(parts[j], options);
1913
2103
  matchers[i] = partMatchers;
1914
2104
  }
1915
2105
  return (input) => {
1916
2106
  const inputParts = input.split("/");
1917
2107
  if (inputParts[0] === ".." && ONLY_PARENT_DIRECTORIES.test(input)) return true;
1918
- for (let i = 0; i < patterns.length; i++) {
2108
+ for (i = 0; i < patternsCount; i++) {
1919
2109
  const patternParts = patternsParts[i];
1920
2110
  const matcher = matchers[i];
1921
2111
  const inputPatternCount = inputParts.length;
1922
2112
  const minParts = Math.min(inputPatternCount, patternParts.length);
1923
- let j = 0;
2113
+ j = 0;
1924
2114
  while (j < minParts) {
1925
2115
  const part = patternParts[j];
1926
2116
  if (part.includes("/")) return true;
1927
2117
  if (!matcher[j](inputParts[j])) break;
1928
- if (globstarEnabled && part === "**") return true;
2118
+ if (!options.noglobstar && part === "**") return true;
1929
2119
  j++;
1930
2120
  }
1931
2121
  if (j === inputPatternCount) return true;
@@ -1938,7 +2128,7 @@ const isRoot = isWin ? (p) => WIN32_ROOT_DIR.test(p) : (p) => p === "/";
1938
2128
  function buildFormat(cwd, root, absolute) {
1939
2129
  if (cwd === root || root.startsWith(`${cwd}/`)) {
1940
2130
  if (absolute) {
1941
- const start = isRoot(cwd) ? cwd.length : cwd.length + 1;
2131
+ const start = cwd.length + +!isRoot(cwd);
1942
2132
  return (p, isDir) => p.slice(start, isDir ? -1 : void 0) || ".";
1943
2133
  }
1944
2134
  const prefix = root.slice(cwd.length + 1);
@@ -1959,28 +2149,27 @@ function buildRelative(cwd, root) {
1959
2149
  }
1960
2150
  return (p) => {
1961
2151
  const result = posix.relative(cwd, `${root}/${p}`);
1962
- if (p.endsWith("/") && result !== "") return `${result}/`;
1963
- return result || ".";
2152
+ return p[p.length - 1] === "/" && result !== "" ? `${result}/` : result || ".";
1964
2153
  };
1965
2154
  }
1966
2155
  const splitPatternOptions = { parts: true };
1967
- function splitPattern(path$1) {
2156
+ function splitPattern(path) {
1968
2157
  var _result$parts;
1969
- const result = import_picomatch.default.scan(path$1, splitPatternOptions);
1970
- return ((_result$parts = result.parts) === null || _result$parts === void 0 ? void 0 : _result$parts.length) ? result.parts : [path$1];
2158
+ const result = import_picomatch.default.scan(path, splitPatternOptions);
2159
+ return ((_result$parts = result.parts) === null || _result$parts === void 0 ? void 0 : _result$parts.length) ? result.parts : [path];
1971
2160
  }
1972
2161
  const ESCAPED_WIN32_BACKSLASHES = /\\(?![()[\]{}!+@])/g;
1973
- function convertPosixPathToPattern(path$1) {
1974
- return escapePosixPath(path$1);
2162
+ function convertPosixPathToPattern(path) {
2163
+ return escapePosixPath(path);
1975
2164
  }
1976
- function convertWin32PathToPattern(path$1) {
1977
- return escapeWin32Path(path$1).replace(ESCAPED_WIN32_BACKSLASHES, "/");
2165
+ function convertWin32PathToPattern(path) {
2166
+ return escapeWin32Path(path).replace(ESCAPED_WIN32_BACKSLASHES, "/");
1978
2167
  }
1979
2168
  const convertPathToPattern = isWin ? convertWin32PathToPattern : convertPosixPathToPattern;
1980
2169
  const POSIX_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}*?|]|^!|[!+@](?=\()|\\(?![()[\]{}!*+?@|]))/g;
1981
2170
  const WIN32_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}]|^!|[!+@](?=\())/g;
1982
- const escapePosixPath = (path$1) => path$1.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&");
1983
- const escapeWin32Path = (path$1) => path$1.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&");
2171
+ const escapePosixPath = (path) => path.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&");
2172
+ const escapeWin32Path = (path) => path.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&");
1984
2173
  const escapePath = isWin ? escapeWin32Path : escapePosixPath;
1985
2174
  function isDynamicPattern(pattern, options) {
1986
2175
  if ((options === null || options === void 0 ? void 0 : options.caseSensitiveMatch) === false) return true;
@@ -1990,28 +2179,31 @@ function isDynamicPattern(pattern, options) {
1990
2179
  function log(...tasks) {
1991
2180
  console.log(`[tinyglobby ${new Date().toLocaleTimeString("es")}]`, ...tasks);
1992
2181
  }
2182
+ function ensureStringArray(value) {
2183
+ return typeof value === "string" ? [value] : value !== null && value !== void 0 ? value : [];
2184
+ }
1993
2185
  const PARENT_DIRECTORY = /^(\/?\.\.)+/;
1994
2186
  const ESCAPING_BACKSLASHES = /\\(?=[()[\]{}!*+?@|])/g;
1995
- const BACKSLASHES = /\\/g;
1996
- function normalizePattern(pattern, expandDirectories, cwd, props, isIgnore) {
2187
+ function normalizePattern(pattern, opts, props, isIgnore) {
2188
+ var _PARENT_DIRECTORY$exe;
2189
+ const cwd = opts.cwd;
1997
2190
  let result = pattern;
1998
- if (pattern.endsWith("/")) result = pattern.slice(0, -1);
1999
- if (!result.endsWith("*") && expandDirectories) result += "/**";
2191
+ if (pattern[pattern.length - 1] === "/") result = pattern.slice(0, -1);
2192
+ if (result[result.length - 1] !== "*" && opts.expandDirectories) result += "/**";
2000
2193
  const escapedCwd = escapePath(cwd);
2001
- if (path.isAbsolute(result.replace(ESCAPING_BACKSLASHES, ""))) result = posix.relative(escapedCwd, result);
2002
- else result = posix.normalize(result);
2003
- const parentDirectoryMatch = PARENT_DIRECTORY.exec(result);
2194
+ result = isAbsolute(result.replace(ESCAPING_BACKSLASHES, "")) ? posix.relative(escapedCwd, result) : posix.normalize(result);
2195
+ const parentDir = (_PARENT_DIRECTORY$exe = PARENT_DIRECTORY.exec(result)) === null || _PARENT_DIRECTORY$exe === void 0 ? void 0 : _PARENT_DIRECTORY$exe[0];
2004
2196
  const parts = splitPattern(result);
2005
- if (parentDirectoryMatch === null || parentDirectoryMatch === void 0 ? void 0 : parentDirectoryMatch[0]) {
2006
- const n = (parentDirectoryMatch[0].length + 1) / 3;
2197
+ if (parentDir) {
2198
+ const n = (parentDir.length + 1) / 3;
2007
2199
  let i = 0;
2008
2200
  const cwdParts = escapedCwd.split("/");
2009
2201
  while (i < n && parts[i + n] === cwdParts[cwdParts.length + i - n]) {
2010
2202
  result = result.slice(0, (n - i - 1) * 3) + result.slice((n - i) * 3 + parts[i + n].length + 1) || ".";
2011
2203
  i++;
2012
2204
  }
2013
- const potentialRoot = posix.join(cwd, parentDirectoryMatch[0].slice(i * 3));
2014
- if (!potentialRoot.startsWith(".") && props.root.length > potentialRoot.length) {
2205
+ const potentialRoot = posix.join(cwd, parentDir.slice(i * 3));
2206
+ if (potentialRoot[0] !== "." && props.root.length > potentialRoot.length) {
2015
2207
  props.root = potentialRoot;
2016
2208
  props.depthOffset = -n + i;
2017
2209
  }
@@ -2027,7 +2219,7 @@ function normalizePattern(pattern, expandDirectories, cwd, props, isIgnore) {
2027
2219
  newCommonPath.pop();
2028
2220
  break;
2029
2221
  }
2030
- if (part !== props.commonPath[i] || isDynamicPattern(part) || i === parts.length - 1) break;
2222
+ if (i === parts.length - 1 || part !== props.commonPath[i] || isDynamicPattern(part)) break;
2031
2223
  newCommonPath.push(part);
2032
2224
  }
2033
2225
  props.depthOffset = newCommonPath.length;
@@ -2036,145 +2228,131 @@ function normalizePattern(pattern, expandDirectories, cwd, props, isIgnore) {
2036
2228
  }
2037
2229
  return result;
2038
2230
  }
2039
- function processPatterns({ patterns = ["**/*"], ignore = [], expandDirectories = true }, cwd, props) {
2040
- if (typeof patterns === "string") patterns = [patterns];
2041
- if (typeof ignore === "string") ignore = [ignore];
2231
+ function processPatterns(options, patterns, props) {
2042
2232
  const matchPatterns = [];
2043
2233
  const ignorePatterns = [];
2044
- for (const pattern of ignore) {
2234
+ for (const pattern of options.ignore) {
2045
2235
  if (!pattern) continue;
2046
- if (pattern[0] !== "!" || pattern[1] === "(") ignorePatterns.push(normalizePattern(pattern, expandDirectories, cwd, props, true));
2236
+ if (pattern[0] !== "!" || pattern[1] === "(") ignorePatterns.push(normalizePattern(pattern, options, props, true));
2047
2237
  }
2048
2238
  for (const pattern of patterns) {
2049
2239
  if (!pattern) continue;
2050
- if (pattern[0] !== "!" || pattern[1] === "(") matchPatterns.push(normalizePattern(pattern, expandDirectories, cwd, props, false));
2051
- else if (pattern[1] !== "!" || pattern[2] === "(") ignorePatterns.push(normalizePattern(pattern.slice(1), expandDirectories, cwd, props, true));
2240
+ if (pattern[0] !== "!" || pattern[1] === "(") matchPatterns.push(normalizePattern(pattern, options, props, false));
2241
+ else if (pattern[1] !== "!" || pattern[2] === "(") ignorePatterns.push(normalizePattern(pattern.slice(1), options, props, true));
2052
2242
  }
2053
2243
  return {
2054
2244
  match: matchPatterns,
2055
2245
  ignore: ignorePatterns
2056
2246
  };
2057
2247
  }
2058
- function formatPaths(paths, relative) {
2059
- for (let i = paths.length - 1; i >= 0; i--) {
2060
- const path$1 = paths[i];
2061
- paths[i] = relative(path$1);
2062
- }
2063
- return paths;
2064
- }
2065
- function normalizeCwd(cwd) {
2066
- if (!cwd) return process.cwd().replace(BACKSLASHES, "/");
2067
- if (cwd instanceof URL) return fileURLToPath(cwd).replace(BACKSLASHES, "/");
2068
- return path.resolve(cwd).replace(BACKSLASHES, "/");
2069
- }
2070
- function getCrawler(patterns, inputOptions = {}) {
2071
- const options = process.env.TINYGLOBBY_DEBUG ? {
2072
- ...inputOptions,
2073
- debug: true
2074
- } : inputOptions;
2075
- const cwd = normalizeCwd(options.cwd);
2076
- if (options.debug) log("globbing with:", {
2077
- patterns,
2078
- options,
2079
- cwd
2080
- });
2081
- if (Array.isArray(patterns) && patterns.length === 0) return [{
2082
- sync: () => [],
2083
- withPromise: async () => []
2084
- }, false];
2248
+ function buildCrawler(options, patterns) {
2249
+ const cwd = options.cwd;
2085
2250
  const props = {
2086
2251
  root: cwd,
2087
- commonPath: null,
2088
2252
  depthOffset: 0
2089
2253
  };
2090
- const processed = processPatterns({
2091
- ...options,
2092
- patterns
2093
- }, cwd, props);
2254
+ const processed = processPatterns(options, patterns, props);
2094
2255
  if (options.debug) log("internal processing patterns:", processed);
2256
+ const { absolute, caseSensitiveMatch, debug, dot, followSymbolicLinks, onlyDirectories } = options;
2257
+ const root = props.root.replace(BACKSLASHES, "");
2095
2258
  const matchOptions = {
2096
- dot: options.dot,
2259
+ dot,
2097
2260
  nobrace: options.braceExpansion === false,
2098
- nocase: options.caseSensitiveMatch === false,
2261
+ nocase: !caseSensitiveMatch,
2099
2262
  noextglob: options.extglob === false,
2100
2263
  noglobstar: options.globstar === false,
2101
2264
  posix: true
2102
2265
  };
2103
- const matcher = (0, import_picomatch.default)(processed.match, {
2104
- ...matchOptions,
2105
- ignore: processed.ignore
2106
- });
2266
+ const matcher = (0, import_picomatch.default)(processed.match, matchOptions);
2107
2267
  const ignore = (0, import_picomatch.default)(processed.ignore, matchOptions);
2108
2268
  const partialMatcher = getPartialMatcher(processed.match, matchOptions);
2109
- const format = buildFormat(cwd, props.root, options.absolute);
2110
- const formatExclude = options.absolute ? format : buildFormat(cwd, props.root, true);
2111
- const fdirOptions = {
2112
- filters: [options.debug ? (p, isDirectory) => {
2113
- const path$1 = format(p, isDirectory);
2114
- const matches = matcher(path$1);
2115
- if (matches) log(`matched ${path$1}`);
2269
+ const format = buildFormat(cwd, root, absolute);
2270
+ const excludeFormatter = absolute ? format : buildFormat(cwd, root, true);
2271
+ const excludePredicate = (_, p) => {
2272
+ const relativePath = excludeFormatter(p, true);
2273
+ return relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
2274
+ };
2275
+ let maxDepth;
2276
+ if (options.deep !== void 0) maxDepth = Math.round(options.deep - props.depthOffset);
2277
+ const crawler = new Builder({
2278
+ filters: [debug ? (p, isDirectory) => {
2279
+ const path = format(p, isDirectory);
2280
+ const matches = matcher(path) && !ignore(path);
2281
+ if (matches) log(`matched ${path}`);
2116
2282
  return matches;
2117
- } : (p, isDirectory) => matcher(format(p, isDirectory))],
2118
- exclude: options.debug ? (_, p) => {
2119
- const relativePath = formatExclude(p, true);
2120
- const skipped = relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
2121
- if (skipped) log(`skipped ${p}`);
2122
- else log(`crawling ${p}`);
2283
+ } : (p, isDirectory) => {
2284
+ const path = format(p, isDirectory);
2285
+ return matcher(path) && !ignore(path);
2286
+ }],
2287
+ exclude: debug ? (_, p) => {
2288
+ const skipped = excludePredicate(_, p);
2289
+ log(`${skipped ? "skipped" : "crawling"} ${p}`);
2123
2290
  return skipped;
2124
- } : (_, p) => {
2125
- const relativePath = formatExclude(p, true);
2126
- return relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
2127
- },
2128
- fs: options.fs ? {
2129
- readdir: options.fs.readdir || nativeFs.readdir,
2130
- readdirSync: options.fs.readdirSync || nativeFs.readdirSync,
2131
- realpath: options.fs.realpath || nativeFs.realpath,
2132
- realpathSync: options.fs.realpathSync || nativeFs.realpathSync,
2133
- stat: options.fs.stat || nativeFs.stat,
2134
- statSync: options.fs.statSync || nativeFs.statSync
2135
- } : void 0,
2291
+ } : excludePredicate,
2292
+ fs: options.fs,
2136
2293
  pathSeparator: "/",
2137
- relativePaths: true,
2138
- resolveSymlinks: true,
2294
+ relativePaths: !absolute,
2295
+ resolvePaths: absolute,
2296
+ includeBasePath: absolute,
2297
+ resolveSymlinks: followSymbolicLinks,
2298
+ excludeSymlinks: !followSymbolicLinks,
2299
+ excludeFiles: onlyDirectories,
2300
+ includeDirs: onlyDirectories || !options.onlyFiles,
2301
+ maxDepth,
2139
2302
  signal: options.signal
2303
+ }).crawl(root);
2304
+ if (options.debug) log("internal properties:", {
2305
+ ...props,
2306
+ root
2307
+ });
2308
+ return [crawler, cwd !== root && !absolute && buildRelative(cwd, root)];
2309
+ }
2310
+ function formatPaths(paths, mapper) {
2311
+ if (mapper) for (let i = paths.length - 1; i >= 0; i--) paths[i] = mapper(paths[i]);
2312
+ return paths;
2313
+ }
2314
+ const defaultOptions = {
2315
+ caseSensitiveMatch: true,
2316
+ cwd: process.cwd(),
2317
+ debug: !!process.env.TINYGLOBBY_DEBUG,
2318
+ expandDirectories: true,
2319
+ followSymbolicLinks: true,
2320
+ onlyFiles: true
2321
+ };
2322
+ function getOptions(options) {
2323
+ const opts = {
2324
+ ...defaultOptions,
2325
+ ...options
2140
2326
  };
2141
- if (options.deep !== void 0) fdirOptions.maxDepth = Math.round(options.deep - props.depthOffset);
2142
- if (options.absolute) {
2143
- fdirOptions.relativePaths = false;
2144
- fdirOptions.resolvePaths = true;
2145
- fdirOptions.includeBasePath = true;
2146
- }
2147
- if (options.followSymbolicLinks === false) {
2148
- fdirOptions.resolveSymlinks = false;
2149
- fdirOptions.excludeSymlinks = true;
2150
- }
2151
- if (options.onlyDirectories) {
2152
- fdirOptions.excludeFiles = true;
2153
- fdirOptions.includeDirs = true;
2154
- } else if (options.onlyFiles === false) fdirOptions.includeDirs = true;
2155
- props.root = props.root.replace(BACKSLASHES, "");
2156
- const root = props.root;
2157
- if (options.debug) log("internal properties:", props);
2158
- const relative = cwd !== root && !options.absolute && buildRelative(cwd, props.root);
2159
- return [new Builder(fdirOptions).crawl(root), relative];
2327
+ opts.cwd = (opts.cwd instanceof URL ? fileURLToPath(opts.cwd) : resolve(opts.cwd)).replace(BACKSLASHES, "/");
2328
+ opts.ignore = ensureStringArray(opts.ignore);
2329
+ opts.fs && (opts.fs = {
2330
+ readdir: opts.fs.readdir || readdir,
2331
+ readdirSync: opts.fs.readdirSync || readdirSync,
2332
+ realpath: opts.fs.realpath || realpath,
2333
+ realpathSync: opts.fs.realpathSync || realpathSync,
2334
+ stat: opts.fs.stat || stat,
2335
+ statSync: opts.fs.statSync || statSync
2336
+ });
2337
+ if (opts.debug) log("globbing with options:", opts);
2338
+ return opts;
2339
+ }
2340
+ function getCrawler(globInput, inputOptions = {}) {
2341
+ var _ref;
2342
+ if (globInput && (inputOptions === null || inputOptions === void 0 ? void 0 : inputOptions.patterns)) throw new Error("Cannot pass patterns as both an argument and an option");
2343
+ const isModern = isReadonlyArray(globInput) || typeof globInput === "string";
2344
+ const patterns = ensureStringArray((_ref = isModern ? globInput : globInput.patterns) !== null && _ref !== void 0 ? _ref : "**/*");
2345
+ const options = getOptions(isModern ? inputOptions : globInput);
2346
+ return patterns.length > 0 ? buildCrawler(options, patterns) : [];
2160
2347
  }
2161
- async function glob$1(patternsOrOptions, options) {
2162
- if (patternsOrOptions && (options === null || options === void 0 ? void 0 : options.patterns)) throw new Error("Cannot pass patterns as both an argument and an option");
2163
- const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string";
2164
- const opts = isModern ? options : patternsOrOptions;
2165
- const [crawler, relative] = getCrawler(isModern ? patternsOrOptions : patternsOrOptions.patterns, opts);
2166
- if (!relative) return crawler.withPromise();
2167
- return formatPaths(await crawler.withPromise(), relative);
2348
+ async function glob$1(globInput, options) {
2349
+ const [crawler, relative] = getCrawler(globInput, options);
2350
+ return crawler ? formatPaths(await crawler.withPromise(), relative) : [];
2168
2351
  }
2169
- function globSync$1(patternsOrOptions, options) {
2170
- if (patternsOrOptions && (options === null || options === void 0 ? void 0 : options.patterns)) throw new Error("Cannot pass patterns as both an argument and an option");
2171
- const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string";
2172
- const opts = isModern ? options : patternsOrOptions;
2173
- const [crawler, relative] = getCrawler(isModern ? patternsOrOptions : patternsOrOptions.patterns, opts);
2174
- if (!relative) return crawler.sync();
2175
- return formatPaths(crawler.sync(), relative);
2352
+ function globSync$1(globInput, options) {
2353
+ const [crawler, relative] = getCrawler(globInput, options);
2354
+ return crawler ? formatPaths(crawler.sync(), relative) : [];
2176
2355
  }
2177
-
2178
2356
  //#endregion
2179
2357
  //#region src/fs/glob.ts
2180
2358
  const normalizeArgs = (patternsOrOptions, maybeOptions) => {
@@ -2198,10 +2376,129 @@ function globSync(...args) {
2198
2376
  ...options
2199
2377
  });
2200
2378
  }
2201
-
2202
2379
  //#endregion
2203
- //#region src/fs/safe.ts
2204
- const pathLikeToPath = (pathLike) => path$1.resolve(pathLike instanceof URL ? pathLike.pathname : pathLike);
2380
+ //#region src/fs/vfile.ts
2381
+ const nil$1 = nil$2;
2382
+ var BaseVFile = class BaseVFile {
2383
+ _cwd = process.cwd();
2384
+ _dirname = "";
2385
+ _filename = "";
2386
+ _extname = "";
2387
+ constructor(filepath, cwd) {
2388
+ if (cwd) this.cwd(cwd);
2389
+ const pathname = isString(filepath) ? filepath : url.fileURLToPath(filepath);
2390
+ if (path.isAbsolute(pathname)) this.pathname(pathname);
2391
+ else this.pathname.relative(pathname);
2392
+ }
2393
+ cwd(cwd) {
2394
+ if (cwd === void 0) return this._cwd;
2395
+ this._cwd = cwd;
2396
+ return this;
2397
+ }
2398
+ get pathname() {
2399
+ const obj = this.absolutePathname.bind(this);
2400
+ obj.relative = this.relativePathname.bind(this);
2401
+ return obj;
2402
+ }
2403
+ get dirname() {
2404
+ const obj = this.relativeDirname.bind(this);
2405
+ obj.absolute = this.absoluteDirname.bind(this);
2406
+ return obj;
2407
+ }
2408
+ filename(filename) {
2409
+ if (filename === void 0) return this._filename;
2410
+ this._filename = filename;
2411
+ return this;
2412
+ }
2413
+ extname(extname) {
2414
+ if (extname === void 0) return this._extname;
2415
+ this._extname = extname;
2416
+ return this;
2417
+ }
2418
+ basename(basename) {
2419
+ if (basename === void 0) {
2420
+ if (!this._extname) return this._filename;
2421
+ return this._filename + "." + this._extname;
2422
+ }
2423
+ const { name, ext } = path.parse(basename);
2424
+ this._filename = name;
2425
+ this._extname = removePrefix(".", ext);
2426
+ return this;
2427
+ }
2428
+ clone() {
2429
+ const vfile = new BaseVFile("");
2430
+ vfile._cwd = this._cwd;
2431
+ vfile._dirname = this._dirname;
2432
+ vfile._filename = this._filename;
2433
+ vfile._extname = this._extname;
2434
+ return vfile;
2435
+ }
2436
+ absolutePathname(pathname) {
2437
+ if (pathname === void 0) {
2438
+ const basename = this._filename + (this._extname ? "." : "") + this._extname;
2439
+ return path.resolve(this._cwd, this._dirname, basename);
2440
+ }
2441
+ const { dir, name, ext } = path.parse(pathname);
2442
+ this._dirname = path.relative(this._cwd, dir);
2443
+ this._filename = name;
2444
+ this._extname = removePrefix(".", ext);
2445
+ return this;
2446
+ }
2447
+ relativePathname(pathname) {
2448
+ if (pathname === void 0) {
2449
+ const basename = this._filename + (this._extname ? "." : "") + this._extname;
2450
+ return path.join(this._dirname, basename);
2451
+ }
2452
+ const { dir, name, ext } = path.parse(pathname);
2453
+ this._dirname = dir;
2454
+ this._filename = name;
2455
+ this._extname = removePrefix(".", ext);
2456
+ return this;
2457
+ }
2458
+ relativeDirname(dirname) {
2459
+ if (dirname === void 0) return this._dirname;
2460
+ this._dirname = dirname;
2461
+ return this;
2462
+ }
2463
+ absoluteDirname(dirname) {
2464
+ if (dirname === void 0) return path.resolve(this._cwd, this._dirname);
2465
+ this._dirname = path.relative(this._cwd, dirname);
2466
+ return this;
2467
+ }
2468
+ };
2469
+ var ExtendVFile = class ExtendVFile extends BaseVFile {
2470
+ _encoding = "utf-8";
2471
+ _linebreak = "\n";
2472
+ _transformer;
2473
+ _raw = nil$1;
2474
+ _value = nil$1;
2475
+ encoding(encoding) {
2476
+ if (encoding === void 0) return this._encoding;
2477
+ this._encoding = encoding;
2478
+ return this;
2479
+ }
2480
+ linebreak(linebreak) {
2481
+ if (linebreak === void 0) return this._linebreak;
2482
+ this._linebreak = linebreak;
2483
+ return this;
2484
+ }
2485
+ clone() {
2486
+ const vfile = new ExtendVFile("");
2487
+ vfile._cwd = this._cwd;
2488
+ vfile._dirname = this._dirname;
2489
+ vfile._filename = this._filename;
2490
+ vfile._extname = this._extname;
2491
+ vfile._encoding = this._encoding;
2492
+ vfile._linebreak = this._linebreak;
2493
+ vfile._transformer = this._transformer;
2494
+ vfile._raw = this._raw;
2495
+ vfile._value = this._value;
2496
+ return vfile;
2497
+ }
2498
+ };
2499
+ //#endregion
2500
+ //#region src/fs/utils.ts
2501
+ const pathLikeToPath = (pathLike) => path.resolve(pathLike instanceof URL ? url.fileURLToPath(pathLike) : pathLike);
2205
2502
  const parseEncodingOptions = (options) => {
2206
2503
  const encoding = options?.encoding || "utf-8";
2207
2504
  return encoding === "buffer" ? {} : { encoding };
@@ -2216,86 +2513,88 @@ const parseWriteJsonOptions = (options) => {
2216
2513
  encoding: parseEncodingOptions(options)
2217
2514
  };
2218
2515
  };
2219
- const appendFile$1 = async (path, data, options) => Result.gen(async function* () {
2220
- const newline = options?.newline ?? true;
2221
- yield* await mkdir$1(dirname$1(pathLikeToPath(path).toString()));
2222
- const fn = async () => {
2223
- await promises.appendFile(path, newline ? `\n${data}` : data, parseEncodingOptions(options));
2224
- };
2225
- return (await Result.try(fn, Error)).context(`Failed to append file: ${path}`);
2226
- });
2227
- const appendFileSync$1 = (path, data, options) => Result.gen(function* () {
2228
- const newline = options?.newline ?? true;
2229
- yield* mkdirSync$1(dirname$1(pathLikeToPath(path).toString()));
2230
- const fn = () => {
2231
- fs.appendFileSync(path, newline ? `\n${data}` : data, parseEncodingOptions(options));
2232
- };
2233
- return Result.try(fn, Error).context(`Failed to append file: ${path}`);
2234
- });
2235
- const cp$1 = async (source, destination, options) => {
2236
- const { recursive = true } = options || {};
2237
- const fn = async () => {
2238
- await promises.cp(source, destination, { recursive });
2239
- };
2240
- return (await Result.try(fn, Error)).context(`Failed to copy path: ${source} to ${destination}`);
2241
- };
2242
- const cpSync$1 = (source, destination, options) => {
2243
- const { recursive = true } = options || {};
2244
- const fn = () => {
2245
- fs.cpSync(source, destination, { recursive });
2246
- };
2247
- return Result.try(fn, Error).context(`Failed to copy path: ${source} to ${destination}`);
2248
- };
2249
- const exists$1 = async (path) => {
2250
- const fn = async () => {
2516
+ //#endregion
2517
+ //#region src/fs/safe/exists.ts
2518
+ const exists = async (path) => {
2519
+ try {
2251
2520
  await promises.access(path);
2252
2521
  return true;
2253
- };
2254
- return (await Result.try(fn, Error)).context(`Failed to check exists for path: ${path}`);
2522
+ } catch {
2523
+ return false;
2524
+ }
2255
2525
  };
2256
- const existsSync$1 = (path) => {
2257
- const fn = () => {
2526
+ const existsSync = (path) => {
2527
+ try {
2258
2528
  fs.accessSync(path);
2259
2529
  return true;
2260
- };
2261
- return Result.try(fn, Error).context(`Failed to check exists for path: ${path}`);
2530
+ } catch {
2531
+ return false;
2532
+ }
2262
2533
  };
2534
+ //#endregion
2535
+ //#region src/fs/safe/mkdir.ts
2536
+ const safeMkdir = Result.wrap(promises.mkdir, Error);
2263
2537
  const mkdir$1 = async (path, options) => {
2264
2538
  const { recursive = true } = options || {};
2265
- if ((await exists$1(path)).isOk()) return ok();
2266
- const fn = async () => {
2267
- await promises.mkdir(path, { recursive });
2268
- };
2269
- return (await Result.try(fn, Error)).context(`Failed to create directory: ${path}`);
2539
+ if (await exists(path)) return ok();
2540
+ return (await safeMkdir(path, { recursive })).and(ok()).context(`Failed to create directory: ${path}`);
2270
2541
  };
2542
+ const safeMkdirSync = Result.wrap(fs.mkdirSync, Error);
2271
2543
  const mkdirSync$1 = (path, options) => {
2272
2544
  const { recursive = true } = options || {};
2273
- if (existsSync$1(path).isOk()) return ok();
2274
- const fn = () => {
2275
- fs.mkdirSync(path, { recursive });
2276
- };
2277
- return Result.try(fn, Error).context(`Failed to create directory: ${path}`);
2545
+ if (existsSync(path)) return ok();
2546
+ return safeMkdirSync(path, { recursive }).and(ok()).context(`Failed to create directory: ${path}`);
2278
2547
  };
2548
+ //#endregion
2549
+ //#region src/fs/safe/append.ts
2550
+ const safeAppendFile = Result.wrap(promises.appendFile, Error);
2551
+ const appendFile$1 = async (path, data, options) => Result.gen(async function* () {
2552
+ const newline = options?.newline ?? true;
2553
+ yield* await mkdir$1(dirname(pathLikeToPath(path).toString()));
2554
+ return (await safeAppendFile(path, newline ? `\n${data}` : data, parseEncodingOptions(options))).context(`Failed to append file: ${path}`);
2555
+ });
2556
+ const safeAppendFileSync = Result.wrap(fs.appendFileSync, Error);
2557
+ const appendFileSync$1 = (path, data, options) => Result.gen(function* () {
2558
+ const newline = options?.newline ?? true;
2559
+ yield* mkdirSync$1(dirname(pathLikeToPath(path).toString()));
2560
+ return safeAppendFileSync(path, newline ? `\n${data}` : data, parseEncodingOptions(options)).context(`Failed to append file: ${path}`);
2561
+ });
2562
+ //#endregion
2563
+ //#region src/fs/safe/cp.ts
2564
+ const safeCp = Result.wrap(promises.cp, Error);
2565
+ const cp$1 = async (source, destination, options) => {
2566
+ const { recursive = true } = options || {};
2567
+ return (await safeCp(source, destination, { recursive })).context(`Failed to copy path: ${source} to ${destination}`);
2568
+ };
2569
+ const safeCpSync = Result.wrap(fs.cpSync, Error);
2570
+ const cpSync$1 = (source, destination, options) => {
2571
+ const { recursive = true } = options || {};
2572
+ return safeCpSync(source, destination, { recursive }).context(`Failed to copy path: ${source} to ${destination}`);
2573
+ };
2574
+ //#endregion
2575
+ //#region src/fs/safe/read.ts
2576
+ const safeReadFile = Result.wrap(promises.readFile, Error);
2279
2577
  async function readFile$1(path, options) {
2280
- return Result.gen(async function* () {
2281
- yield* await exists$1(path);
2282
- const fn = async () => {
2283
- return await promises.readFile(path, parseEncodingOptions(options));
2284
- };
2285
- return (await Result.try(fn, Error)).context(`Failed to read file: ${path}`);
2286
- });
2578
+ if (!await exists(path)) return err(new Error(`File does not exist: ${path}`));
2579
+ return (await safeReadFile(path, parseEncodingOptions(options))).context(`Failed to read file: ${path}`);
2287
2580
  }
2581
+ const safeReadFileSync = Result.wrap(fs.readFileSync, Error);
2288
2582
  function readFileSync$1(path, options) {
2289
- return Result.gen(function* () {
2290
- yield* existsSync$1(path);
2291
- const fn = () => {
2292
- return fs.readFileSync(path, parseEncodingOptions(options));
2293
- };
2294
- return Result.try(fn, Error).context(`Failed to read file: ${path}`);
2295
- });
2583
+ if (!existsSync(path)) return err(new Error(`File does not exist: ${path}`));
2584
+ return safeReadFileSync(path, parseEncodingOptions(options)).context(`Failed to read file: ${path}`);
2296
2585
  }
2297
- const readFileByLine$1 = (path, options) => Result.gen(async function* () {
2298
- yield* await exists$1(path);
2586
+ const readJson$1 = async (path, options) => Result.gen(async function* () {
2587
+ const content = yield* await readFile$1(path, options);
2588
+ if (!content) return err(new Error(`JSON file is empty: ${path}`));
2589
+ return parse(content).context(`Failed to parse JSON file: ${path}`);
2590
+ });
2591
+ const readJsonSync$1 = (path, options) => Result.gen(function* () {
2592
+ const content = yield* readFileSync$1(path, options);
2593
+ if (!content) return err(new Error(`JSON file is empty: ${path}`));
2594
+ return parse(content).context(`Failed to parse JSON file: ${path}`);
2595
+ });
2596
+ const readFileByLine$1 = async (path, options) => {
2597
+ if (!await exists(path)) return err(new Error(`File does not exist: ${path}`));
2299
2598
  const { createInterface } = await import("node:readline");
2300
2599
  const fn = () => {
2301
2600
  const stream = fs.createReadStream(path, {
@@ -2311,194 +2610,367 @@ const readFileByLine$1 = (path, options) => Result.gen(async function* () {
2311
2610
  });
2312
2611
  };
2313
2612
  return Result.try(fn, Error).context(`Failed to read file: ${path}`);
2314
- });
2315
- const readJson$1 = async (path, options) => Result.gen(async function* () {
2316
- const content = yield* await readFile$1(path, options);
2317
- if (!content) return err(new Error(`JSON file is empty: ${path}`));
2318
- return safeParse(content).context(`Failed to parse JSON file: ${path}`);
2319
- });
2320
- const readJsonSync$1 = (path, options) => Result.gen(function* () {
2321
- const content = yield* readFileSync$1(path, options);
2322
- if (!content) return err(new Error(`JSON file is empty: ${path}`));
2323
- return safeParse(content).context(`Failed to parse JSON file: ${path}`);
2324
- });
2613
+ };
2614
+ //#endregion
2615
+ //#region src/fs/safe/rm.ts
2616
+ const safeRm = Result.wrap(promises.rm, Error);
2325
2617
  const rm$1 = async (path, options) => {
2326
2618
  const { force = true, recursive = true } = options || {};
2327
- const fn = async () => {
2328
- await promises.rm(path, {
2329
- force,
2330
- recursive
2331
- });
2332
- };
2333
- return (await Result.try(fn, Error)).context(`Failed to remove path: ${path}`);
2619
+ return (await safeRm(path, {
2620
+ force,
2621
+ recursive
2622
+ })).context(`Failed to remove path: ${path}`);
2334
2623
  };
2624
+ const safeRmSync = Result.wrap(fs.rmSync, Error);
2335
2625
  const rmSync$1 = (path, options) => {
2336
2626
  const { force = true, recursive = true } = options || {};
2337
- const fn = () => {
2338
- fs.rmSync(path, {
2339
- force,
2340
- recursive
2341
- });
2342
- };
2343
- return Result.try(fn, Error).context(`Failed to remove path: ${path}`);
2627
+ return safeRmSync(path, {
2628
+ force,
2629
+ recursive
2630
+ }).context(`Failed to remove path: ${path}`);
2344
2631
  };
2632
+ //#endregion
2633
+ //#region src/fs/safe/write.ts
2634
+ const safeWriteFile = Result.wrap(promises.writeFile, Error);
2345
2635
  const writeFile = async (path, data, options) => Result.gen(async function* () {
2346
- yield* await mkdir$1(dirname$1(pathLikeToPath(path).toString()));
2347
- const fn = async () => {
2348
- await promises.writeFile(path, data, parseEncodingOptions(options));
2349
- };
2350
- return (await Result.try(fn, Error)).context(`Failed to write file: ${path}`);
2636
+ yield* await mkdir$1(dirname(pathLikeToPath(path).toString()));
2637
+ return (await safeWriteFile(path, data, parseEncodingOptions(options))).context(`Failed to write file: ${path}`);
2351
2638
  });
2352
- const writeFileSync = (path, data, options) => {
2353
- const fn = () => {
2354
- fs.writeFileSync(path, data, parseEncodingOptions(options));
2355
- };
2356
- return Result.try(fn, Error).context(`Failed to write file: ${path}`);
2357
- };
2358
- const writeJson = async (path, data, indentOrOptions) => {
2639
+ const safeWriteFileSync = Result.wrap(fs.writeFileSync, Error);
2640
+ const writeFileSync = (path, data, options) => Result.gen(function* () {
2641
+ yield* mkdirSync$1(dirname(pathLikeToPath(path).toString()));
2642
+ return safeWriteFileSync(path, data, parseEncodingOptions(options)).context(`Failed to write file: ${path}`);
2643
+ });
2644
+ const writeJson = async (path, data, indentOrOptions) => Result.gen(async function* () {
2359
2645
  const { indent, encoding } = parseWriteJsonOptions(indentOrOptions);
2360
- return writeFile(path, stringify(data, null, indent) ?? "", encoding);
2361
- };
2362
- const writeJsonSync = (path, data, indentOrOptions) => {
2646
+ return writeFile(path, yield* stringify(data, null, indent), encoding);
2647
+ });
2648
+ const writeJsonSync = (path, data, indentOrOptions) => Result.gen(function* () {
2363
2649
  const { indent, encoding } = parseWriteJsonOptions(indentOrOptions);
2364
- return writeFileSync(path, stringify(data, null, indent) ?? "", encoding);
2650
+ return writeFileSync(path, yield* stringify(data, null, indent), encoding);
2651
+ });
2652
+ //#endregion
2653
+ //#region src/fs/safe/vfile.ts
2654
+ const nil = nil$2;
2655
+ var VFile = class extends ExtendVFile {
2656
+ transformer(transformer, indent = 2) {
2657
+ if (transformer === void 0) return this._transformer;
2658
+ if (transformer === "json") this._transformer = {
2659
+ parse,
2660
+ stringify: (value) => stringify(value, null, indent)
2661
+ };
2662
+ else this._transformer = transformer;
2663
+ return this;
2664
+ }
2665
+ raw(raw) {
2666
+ if (raw !== void 0) {
2667
+ this._raw = raw;
2668
+ this._value = nil;
2669
+ return this;
2670
+ }
2671
+ if (!isNil(this._raw)) return ok(this._raw);
2672
+ if (isNil(this._value)) return err(new Error("No content")).context("Failed to get raw content");
2673
+ return this.stringifyValue(this._value).inspect((raw) => {
2674
+ this._raw = raw;
2675
+ });
2676
+ }
2677
+ value(value) {
2678
+ if (value !== void 0) {
2679
+ this._value = value;
2680
+ this._raw = nil;
2681
+ return this;
2682
+ }
2683
+ if (this._value !== nil) return ok(this._value);
2684
+ if (this._raw === nil) return err(new Error("No content")).context("Failed to get value");
2685
+ return this.parseRaw(this._raw).inspect((value) => {
2686
+ this._value = value;
2687
+ });
2688
+ }
2689
+ lines() {
2690
+ return this.raw().map((raw) => raw.split(this._linebreak));
2691
+ }
2692
+ append(value, newline = true) {
2693
+ return Result.gen(function* () {
2694
+ const linebreak = newline ? this._linebreak : "";
2695
+ const append = yield* this.stringifyValue(value);
2696
+ if (isNil(this._raw) || isNil(this._value)) this.raw(append);
2697
+ else this.raw(this._raw + linebreak + append);
2698
+ }, this);
2699
+ }
2700
+ async exists() {
2701
+ return exists(this.pathname());
2702
+ }
2703
+ existsSync() {
2704
+ return existsSync(this.pathname());
2705
+ }
2706
+ async cp(destination, options) {
2707
+ return cp$1(this.pathname(), destination, options);
2708
+ }
2709
+ cpSync(destination, options) {
2710
+ return cpSync$1(this.pathname(), destination, options);
2711
+ }
2712
+ async rm(options) {
2713
+ return rm$1(this.pathname(), options);
2714
+ }
2715
+ rmSync(options) {
2716
+ return rmSync$1(this.pathname(), options);
2717
+ }
2718
+ async read() {
2719
+ return (await readFile$1(this.pathname(), this.encodingOptions)).andThen((raw) => {
2720
+ this.raw(raw);
2721
+ return this.value();
2722
+ });
2723
+ }
2724
+ readSync() {
2725
+ return readFileSync$1(this.pathname(), this.encodingOptions).andThen((raw) => {
2726
+ this.raw(raw);
2727
+ return this.value();
2728
+ });
2729
+ }
2730
+ readByLine() {
2731
+ return readFileByLine$1(this.pathname(), this.encodingOptions);
2732
+ }
2733
+ async write() {
2734
+ const result = this.raw();
2735
+ if (result.isErr()) return result;
2736
+ return writeFile(this.pathname(), result.unwrap(), this.encodingOptions);
2737
+ }
2738
+ writeSync() {
2739
+ const result = this.raw();
2740
+ if (result.isErr()) return result;
2741
+ return writeFileSync(this.pathname(), result.unwrap(), this.encodingOptions);
2742
+ }
2743
+ get encodingOptions() {
2744
+ return { encoding: this._encoding };
2745
+ }
2746
+ parseRaw(raw) {
2747
+ if (!this._transformer?.parse) return ok(raw);
2748
+ return this._transformer.parse(raw).context("Failed to parse raw content");
2749
+ }
2750
+ stringifyValue(value) {
2751
+ if (!this._transformer?.stringify) return ok(value);
2752
+ return this._transformer.stringify(value).context("Failed to stringify value");
2753
+ }
2365
2754
  };
2366
-
2367
2755
  //#endregion
2368
- //#region src/fs/unsafe.ts
2756
+ //#region src/fs/unsafe/mkdir.ts
2757
+ const mkdir = async (path, options) => {
2758
+ const { recursive = true } = options || {};
2759
+ if (await exists(path)) return;
2760
+ await promises.mkdir(path, { recursive });
2761
+ };
2762
+ const mkdirSync = (path, options) => {
2763
+ const { recursive = true } = options || {};
2764
+ if (existsSync(path)) return;
2765
+ fs.mkdirSync(path, { recursive });
2766
+ };
2767
+ //#endregion
2768
+ //#region src/fs/unsafe/append.ts
2369
2769
  const appendFile = async (path, data, options) => {
2370
- await appendFile$1(path, data, options);
2770
+ const newline = options?.newline ?? true;
2771
+ await mkdir(dirname(pathLikeToPath(path).toString()));
2772
+ await promises.appendFile(path, newline ? `\n${data}` : data, parseEncodingOptions(options));
2371
2773
  };
2372
2774
  const appendFileSync = (path, data, options) => {
2373
- appendFileSync$1(path, data, options);
2775
+ const newline = options?.newline ?? true;
2776
+ mkdirSync(dirname(pathLikeToPath(path).toString()));
2777
+ fs.appendFileSync(path, newline ? `\n${data}` : data, parseEncodingOptions(options));
2374
2778
  };
2779
+ //#endregion
2780
+ //#region src/fs/unsafe/cp.ts
2375
2781
  const cp = async (source, destination, options) => {
2376
- await cp$1(source, destination, options);
2782
+ const { recursive = true } = options || {};
2783
+ await promises.cp(source, destination, { recursive });
2377
2784
  };
2378
2785
  const cpSync = (source, destination, options) => {
2379
- cpSync$1(source, destination, options);
2380
- };
2381
- const exists = async (path) => {
2382
- return (await exists$1(path)).isOk();
2383
- };
2384
- const existsSync = (path) => {
2385
- return existsSync$1(path).isOk();
2386
- };
2387
- const mkdir = async (path, options) => {
2388
- await mkdir$1(path, options);
2389
- };
2390
- const mkdirSync = (path, options) => {
2391
- mkdirSync$1(path, options);
2786
+ const { recursive = true } = options || {};
2787
+ fs.cpSync(source, destination, { recursive });
2392
2788
  };
2789
+ //#endregion
2790
+ //#region src/fs/unsafe/read.ts
2393
2791
  async function readFile(path, options) {
2394
- const result = await readFile$1(path, options);
2395
- if (result.isErr()) return void 0;
2396
- return result.unwrap(null);
2792
+ if (!await exists(path)) return nil$2;
2793
+ try {
2794
+ return await promises.readFile(path, parseEncodingOptions(options));
2795
+ } catch {
2796
+ return nil$2;
2797
+ }
2397
2798
  }
2398
2799
  function readFileSync(path, options) {
2399
- const result = readFileSync$1(path, options);
2400
- if (result.isErr()) return void 0;
2401
- return result.unwrap(null);
2800
+ if (!existsSync(path)) return nil$2;
2801
+ try {
2802
+ return fs.readFileSync(path, parseEncodingOptions(options));
2803
+ } catch {
2804
+ return nil$2;
2805
+ }
2402
2806
  }
2403
- const readFileByLine = async (path, options) => {
2404
- const result = await readFileByLine$1(path, options);
2405
- if (result.isErr()) return void 0;
2406
- return result.unwrap(null);
2407
- };
2408
2807
  const readJson = async (path, options) => {
2409
- const result = await readJson$1(path, options);
2410
- if (result.isErr()) return void 0;
2411
- return result.unwrap(null);
2808
+ const content = await readFile(path, options);
2809
+ if (isNil(content)) return nil$2;
2810
+ return parse$1(content);
2412
2811
  };
2413
2812
  const readJsonSync = (path, options) => {
2414
- const result = readJsonSync$1(path, options);
2415
- if (result.isErr()) return void 0;
2416
- return result.unwrap(null);
2813
+ const content = readFileSync(path, options);
2814
+ if (isNil(content)) return nil$2;
2815
+ return parse$1(content);
2417
2816
  };
2817
+ const readFileByLine = async (path, options) => {
2818
+ if (!await exists(path)) return null;
2819
+ const { createInterface } = await import("node:readline");
2820
+ try {
2821
+ const stream = fs.createReadStream(path, {
2822
+ ...parseEncodingOptions(options),
2823
+ autoClose: true
2824
+ });
2825
+ stream.on("error", (error) => {
2826
+ throw error;
2827
+ });
2828
+ return createInterface({
2829
+ input: stream,
2830
+ crlfDelay: Infinity
2831
+ });
2832
+ } catch {
2833
+ return null;
2834
+ }
2835
+ };
2836
+ //#endregion
2837
+ //#region src/fs/unsafe/rm.ts
2418
2838
  const rm = async (path, options) => {
2419
- await rm$1(path, options);
2839
+ const { force = true, recursive = true } = options || {};
2840
+ await promises.rm(path, {
2841
+ force,
2842
+ recursive
2843
+ });
2420
2844
  };
2421
2845
  const rmSync = (path, options) => {
2422
- rmSync$1(path, options);
2846
+ const { force = true, recursive = true } = options || {};
2847
+ fs.rmSync(path, {
2848
+ force,
2849
+ recursive
2850
+ });
2423
2851
  };
2852
+ //#endregion
2853
+ //#region src/fs/unsafe/write.ts
2424
2854
  const writeFile$1 = async (path, data, options) => {
2425
- await writeFile(path, data, options);
2855
+ await mkdir(dirname(pathLikeToPath(path).toString()));
2856
+ await promises.writeFile(path, data, parseEncodingOptions(options));
2426
2857
  };
2427
2858
  const writeFileSync$1 = (path, data, options) => {
2428
- writeFileSync(path, data, options);
2859
+ mkdirSync(dirname(pathLikeToPath(path).toString()));
2860
+ fs.writeFileSync(path, data, parseEncodingOptions(options));
2429
2861
  };
2430
2862
  const writeJson$1 = async (path, data, indentOrOptions) => {
2431
- await writeJson(path, data, indentOrOptions);
2863
+ const { indent, encoding } = parseWriteJsonOptions(indentOrOptions);
2864
+ const content = stringify$1(data, null, indent);
2865
+ if (isNil(content)) throw new TypeError(`Value cannot be stringified: ${String(data)}`);
2866
+ return writeFile$1(path, content, encoding);
2432
2867
  };
2433
2868
  const writeJsonSync$1 = (path, data, indentOrOptions) => {
2434
- writeJsonSync(path, data, indentOrOptions);
2869
+ const { indent, encoding } = parseWriteJsonOptions(indentOrOptions);
2870
+ const content = stringify$1(data, null, indent);
2871
+ if (isNil(content)) throw new TypeError(`Value cannot be stringified: ${String(data)}`);
2872
+ return writeFileSync$1(path, content, encoding);
2435
2873
  };
2436
-
2437
2874
  //#endregion
2438
- //#region src/fs/vfile.ts
2439
- var VFile = class VFile {
2440
- static async fromFilepath(pathname, cwd) {
2441
- const vfile = new VFile({
2442
- pathname,
2443
- cwd
2444
- });
2445
- return (await readFile$1(pathname)).map((content) => {
2446
- vfile.content = content;
2447
- return vfile;
2448
- });
2875
+ //#region src/fs/unsafe/vfile.ts
2876
+ var VFile$1 = class extends ExtendVFile {
2877
+ transformer(transformer, indent = 2) {
2878
+ if (transformer === void 0) return this._transformer;
2879
+ if (transformer === "json") this._transformer = {
2880
+ parse: parse$1,
2881
+ stringify: (value) => stringify$1(value, null, indent)
2882
+ };
2883
+ else this._transformer = transformer;
2884
+ return this;
2449
2885
  }
2450
- content = "";
2451
- cwd = process.cwd();
2452
- dirname = "";
2453
- filename = "";
2454
- extname = "";
2455
- constructor(options) {
2456
- const { pathname, content, cwd } = options;
2457
- if (content) this.content = content;
2458
- if (cwd) this.cwd = cwd;
2459
- if (path$1.isAbsolute(pathname)) this.pathname = pathname;
2460
- else this.relativePathname = pathname;
2886
+ raw(raw) {
2887
+ if (raw !== void 0) {
2888
+ this._raw = raw;
2889
+ this._value = nil$2;
2890
+ return this;
2891
+ }
2892
+ if (!isNil(this._raw)) return this._raw;
2893
+ if (isNil(this._value)) return nil$2;
2894
+ this._raw = this.stringifyValue(this._value);
2895
+ return this._raw;
2461
2896
  }
2462
- get pathname() {
2463
- return path$1.resolve(this.cwd, this.dirname, this.basename);
2897
+ value(value) {
2898
+ if (value !== void 0) {
2899
+ this._value = value;
2900
+ this._raw = nil$2;
2901
+ return this;
2902
+ }
2903
+ if (!isNil(this._value)) return this._value;
2904
+ if (isNil(this._raw)) return nil$2;
2905
+ this._value = this.parseRaw(this._raw);
2906
+ return this._value;
2464
2907
  }
2465
- set pathname(value) {
2466
- this.parse(value);
2908
+ lines() {
2909
+ const raw = this.raw();
2910
+ if (isNil(raw)) return [];
2911
+ return raw.split(this._linebreak);
2467
2912
  }
2468
- get basename() {
2469
- return this.extname ? this.filename + "." + this.extname : this.filename;
2913
+ append(value, newline = true) {
2914
+ const linebreak = newline ? this._linebreak : "";
2915
+ const append = this.stringifyValue(value);
2916
+ if (isNil(append)) throw new TypeError(`Value cannot be stringified: ${String(value)}`);
2917
+ if (isNil(this._raw) || isNil(this._value)) this.raw(append);
2918
+ else this.raw(this._raw + linebreak + append);
2470
2919
  }
2471
- set basename(value) {
2472
- const { name, ext } = path$1.parse(value);
2473
- this.filename = name;
2474
- this.extname = removePrefix(".", ext);
2920
+ async exists() {
2921
+ return exists(this.pathname());
2475
2922
  }
2476
- get absoluteDirname() {
2477
- return path$1.resolve(this.cwd, this.dirname);
2923
+ existsSync() {
2924
+ return existsSync(this.pathname());
2478
2925
  }
2479
- set absoluteDirname(value) {
2480
- this.dirname = path$1.relative(this.cwd, value);
2926
+ async cp(destination, options) {
2927
+ return cp(this.pathname(), destination, options);
2481
2928
  }
2482
- get relativePathname() {
2483
- return path$1.relative(this.cwd, this.pathname);
2929
+ cpSync(destination, options) {
2930
+ return cpSync(this.pathname(), destination, options);
2484
2931
  }
2485
- set relativePathname(value) {
2486
- this.parse(path$1.resolve(this.cwd, value));
2932
+ async rm(options) {
2933
+ return rm(this.pathname(), options);
2487
2934
  }
2488
- clone() {
2489
- return new VFile({
2490
- pathname: this.pathname,
2491
- content: this.content,
2492
- cwd: this.cwd
2493
- });
2935
+ rmSync(options) {
2936
+ return rmSync(this.pathname(), options);
2937
+ }
2938
+ async read() {
2939
+ const raw = await readFile(this.pathname(), this.encodingOptions);
2940
+ if (isNil(raw)) return nil$2;
2941
+ this.raw(raw);
2942
+ return this.value();
2943
+ }
2944
+ readSync() {
2945
+ const raw = readFileSync(this.pathname(), this.encodingOptions);
2946
+ if (isNil(raw)) return nil$2;
2947
+ this.raw(raw);
2948
+ return this.value();
2949
+ }
2950
+ readByLine() {
2951
+ return readFileByLine(this.pathname(), this.encodingOptions);
2952
+ }
2953
+ async write() {
2954
+ const raw = this.raw();
2955
+ if (isNil(raw)) throw new TypeError("VFile has no content to write");
2956
+ return writeFile$1(this.pathname(), raw, this.encodingOptions);
2957
+ }
2958
+ writeSync() {
2959
+ const raw = this.raw();
2960
+ if (isNil(raw)) throw new TypeError("VFile has no content to write");
2961
+ return writeFileSync$1(this.pathname(), raw, this.encodingOptions);
2962
+ }
2963
+ get encodingOptions() {
2964
+ return { encoding: this._encoding };
2965
+ }
2966
+ parseRaw(raw) {
2967
+ if (!this._transformer?.parse) return raw;
2968
+ return this._transformer.parse(raw);
2494
2969
  }
2495
- parse(value) {
2496
- const { name, ext } = path$1.parse(value);
2497
- this.dirname = path$1.relative(this.cwd, path$1.dirname(value));
2498
- this.filename = name;
2499
- this.extname = removePrefix(".", ext);
2970
+ stringifyValue(value) {
2971
+ if (!this._transformer?.stringify) return value;
2972
+ return this._transformer.stringify(value);
2500
2973
  }
2501
2974
  };
2502
-
2503
2975
  //#endregion
2504
- export { VFile, appendFile, appendFileSync, convertPathToPattern, cp, cpSync, escapePath, exists, existsSync, glob, globSync, isDynamicPattern, mkdir, mkdirSync, readFile, readFileByLine, readFileSync, readJson, readJsonSync, rm, rmSync, appendFile$1 as safeAppendFile, appendFileSync$1 as safeAppendFileSync, cp$1 as safeCp, cpSync$1 as safeCpSync, exists$1 as safeExists, existsSync$1 as safeExistsSync, mkdir$1 as safeMkdir, mkdirSync$1 as safeMkdirSync, readFile$1 as safeReadFile, readFileByLine$1 as safeReadFileByLine, readFileSync$1 as safeReadFileSync, readJson$1 as safeReadJson, readJsonSync$1 as safeReadJsonSync, rm$1 as safeRm, rmSync$1 as safeRmSync, writeFile as safeWriteFile, writeFileSync as safeWriteFileSync, writeJson as safeWriteJson, writeJsonSync as safeWriteJsonSync, writeFile$1 as writeFile, writeFileSync$1 as writeFileSync, writeJson$1 as writeJson, writeJsonSync$1 as writeJsonSync };
2976
+ export { BaseVFile, VFile as SafeVFile, VFile$1 as VFile, appendFile, appendFileSync, convertPathToPattern, cp, cpSync, escapePath, exists, exists as safeExists, existsSync, existsSync as safeExistsSync, glob, globSync, isDynamicPattern, mkdir, mkdirSync, readFile, readFileByLine, readFileSync, readJson, readJsonSync, rm, rmSync, appendFile$1 as safeAppendFile, appendFileSync$1 as safeAppendFileSync, cp$1 as safeCp, cpSync$1 as safeCpSync, mkdir$1 as safeMkdir, mkdirSync$1 as safeMkdirSync, readFile$1 as safeReadFile, readFileByLine$1 as safeReadFileByLine, readFileSync$1 as safeReadFileSync, readJson$1 as safeReadJson, readJsonSync$1 as safeReadJsonSync, rm$1 as safeRm, rmSync$1 as safeRmSync, writeFile as safeWriteFile, writeFileSync as safeWriteFileSync, writeJson as safeWriteJson, writeJsonSync as safeWriteJsonSync, writeFile$1 as writeFile, writeFileSync$1 as writeFileSync, writeJson$1 as writeJson, writeJsonSync$1 as writeJsonSync };