util.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.filenameToSteps = exports.resolve = exports.unixify = exports.isWin = void 0;
  4. exports.isFd = isFd;
  5. exports.validateFd = validateFd;
  6. exports.dataToBuffer = dataToBuffer;
  7. exports.nullCheck = nullCheck;
  8. exports.pathToFilename = pathToFilename;
  9. exports.createError = createError;
  10. exports.createStatError = createStatError;
  11. const path_1 = require("@jsonjoy.com/fs-node-builtins/lib/path");
  12. const buffer_1 = require("@jsonjoy.com/fs-node-builtins/lib/internal/buffer");
  13. const errors = require("@jsonjoy.com/fs-node-builtins/lib/internal/errors");
  14. const process_1 = require("./process");
  15. const encoding_1 = require("./encoding");
  16. const fs_node_utils_1 = require("@jsonjoy.com/fs-node-utils");
  17. exports.isWin = process_1.default.platform === 'win32';
  18. const resolveCrossPlatform = path_1.resolve;
  19. const pathSep = path_1.posix ? path_1.posix.sep : path_1.sep;
  20. const isSeparator = (str, i) => {
  21. let char = str[i];
  22. return i > 0 && (char === '/' || (exports.isWin && char === '\\'));
  23. };
  24. const removeTrailingSeparator = (str) => {
  25. let i = str.length - 1;
  26. if (i < 2)
  27. return str;
  28. while (isSeparator(str, i))
  29. i--;
  30. return str.substr(0, i + 1);
  31. };
  32. const normalizePath = (str, stripTrailing) => {
  33. if (typeof str !== 'string')
  34. throw new TypeError('expected a string');
  35. str = str.replace(/[\\\/]+/g, '/');
  36. if (stripTrailing !== false)
  37. str = removeTrailingSeparator(str);
  38. return str;
  39. };
  40. const unixify = (filepath, stripTrailing = true) => {
  41. if (exports.isWin) {
  42. filepath = normalizePath(filepath, stripTrailing);
  43. return filepath.replace(/^([a-zA-Z]+:|\.\/)/, '');
  44. }
  45. return filepath;
  46. };
  47. exports.unixify = unixify;
  48. let resolve = (filename, base = process_1.default.cwd()) => resolveCrossPlatform(base, filename);
  49. exports.resolve = resolve;
  50. if (exports.isWin) {
  51. const _resolve = resolve;
  52. exports.resolve = resolve = (filename, base) => (0, exports.unixify)(_resolve(filename, base));
  53. }
  54. const filenameToSteps = (filename, base) => {
  55. const fullPath = resolve(filename, base);
  56. const fullPathSansSlash = fullPath.substring(1);
  57. if (!fullPathSansSlash)
  58. return [];
  59. return fullPathSansSlash.split(pathSep);
  60. };
  61. exports.filenameToSteps = filenameToSteps;
  62. function isFd(path) {
  63. return path >>> 0 === path;
  64. }
  65. function validateFd(fd) {
  66. if (!isFd(fd))
  67. throw TypeError(fs_node_utils_1.ERRSTR.FD);
  68. }
  69. function dataToBuffer(data, encoding = encoding_1.ENCODING_UTF8) {
  70. if (buffer_1.Buffer.isBuffer(data))
  71. return data;
  72. else if (data instanceof Uint8Array)
  73. return (0, buffer_1.bufferFrom)(data);
  74. else if (encoding === 'buffer')
  75. return (0, buffer_1.bufferFrom)(String(data), 'utf8');
  76. else
  77. return (0, buffer_1.bufferFrom)(String(data), encoding);
  78. }
  79. function nullCheck(path, callback) {
  80. if (('' + path).indexOf('\u0000') !== -1) {
  81. const er = new Error('Path must be a string without null bytes');
  82. er.code = 'ENOENT';
  83. if (typeof callback !== 'function')
  84. throw er;
  85. Promise.resolve().then(() => callback(er));
  86. return false;
  87. }
  88. return true;
  89. }
  90. function getPathFromURLPosix(url) {
  91. if (url.hostname !== '') {
  92. throw new errors.TypeError('ERR_INVALID_FILE_URL_HOST', process_1.default.platform);
  93. }
  94. const pathname = url.pathname;
  95. for (let n = 0; n < pathname.length; n++) {
  96. if (pathname[n] === '%') {
  97. const third = pathname.codePointAt(n + 2) | 0x20;
  98. if (pathname[n + 1] === '2' && third === 102) {
  99. throw new errors.TypeError('ERR_INVALID_FILE_URL_PATH', 'must not include encoded / characters');
  100. }
  101. }
  102. }
  103. return decodeURIComponent(pathname);
  104. }
  105. function pathToFilename(path) {
  106. if (path instanceof Uint8Array) {
  107. path = (0, buffer_1.bufferFrom)(path);
  108. }
  109. if (typeof path !== 'string' && !buffer_1.Buffer.isBuffer(path)) {
  110. try {
  111. if (!(path instanceof require('url').URL))
  112. throw new TypeError(fs_node_utils_1.ERRSTR.PATH_STR);
  113. }
  114. catch (err) {
  115. throw new TypeError(fs_node_utils_1.ERRSTR.PATH_STR);
  116. }
  117. path = getPathFromURLPosix(path);
  118. }
  119. const pathString = String(path);
  120. nullCheck(pathString);
  121. return pathString;
  122. }
  123. const ENOENT = 'ENOENT';
  124. const EBADF = 'EBADF';
  125. const EINVAL = 'EINVAL';
  126. const EPERM = 'EPERM';
  127. const EPROTO = 'EPROTO';
  128. const EEXIST = 'EEXIST';
  129. const ENOTDIR = 'ENOTDIR';
  130. const EMFILE = 'EMFILE';
  131. const EACCES = 'EACCES';
  132. const EISDIR = 'EISDIR';
  133. const ENOTEMPTY = 'ENOTEMPTY';
  134. const ENOSYS = 'ENOSYS';
  135. const ERR_FS_EISDIR = 'ERR_FS_EISDIR';
  136. const ERR_OUT_OF_RANGE = 'ERR_OUT_OF_RANGE';
  137. function formatError(errorCode, func = '', path = '', path2 = '') {
  138. let pathFormatted = '';
  139. if (path)
  140. pathFormatted = ` '${path}'`;
  141. if (path2)
  142. pathFormatted += ` -> '${path2}'`;
  143. switch (errorCode) {
  144. case ENOENT:
  145. return `ENOENT: no such file or directory, ${func}${pathFormatted}`;
  146. case EBADF:
  147. return `EBADF: bad file descriptor, ${func}${pathFormatted}`;
  148. case EINVAL:
  149. return `EINVAL: invalid argument, ${func}${pathFormatted}`;
  150. case EPERM:
  151. return `EPERM: operation not permitted, ${func}${pathFormatted}`;
  152. case EPROTO:
  153. return `EPROTO: protocol error, ${func}${pathFormatted}`;
  154. case EEXIST:
  155. return `EEXIST: file already exists, ${func}${pathFormatted}`;
  156. case ENOTDIR:
  157. return `ENOTDIR: not a directory, ${func}${pathFormatted}`;
  158. case EISDIR:
  159. return `EISDIR: illegal operation on a directory, ${func}${pathFormatted}`;
  160. case EACCES:
  161. return `EACCES: permission denied, ${func}${pathFormatted}`;
  162. case ENOTEMPTY:
  163. return `ENOTEMPTY: directory not empty, ${func}${pathFormatted}`;
  164. case EMFILE:
  165. return `EMFILE: too many open files, ${func}${pathFormatted}`;
  166. case ENOSYS:
  167. return `ENOSYS: function not implemented, ${func}${pathFormatted}`;
  168. case ERR_FS_EISDIR:
  169. return `[ERR_FS_EISDIR]: Path is a directory: ${func} returned EISDIR (is a directory) ${path}`;
  170. case ERR_OUT_OF_RANGE:
  171. return `[ERR_OUT_OF_RANGE]: value out of range, ${func}${pathFormatted}`;
  172. default:
  173. return `${errorCode}: error occurred, ${func}${pathFormatted}`;
  174. }
  175. }
  176. function createError(errorCode, func = '', path = '', path2 = '', Constructor = Error) {
  177. const error = new Constructor(formatError(errorCode, func, path, path2));
  178. error.code = errorCode;
  179. if (path) {
  180. error.path = path;
  181. }
  182. return error;
  183. }
  184. function createStatError(errorCode, func = '', path = '', path2 = '') {
  185. return {
  186. code: errorCode,
  187. message: formatError(errorCode, func, path, path2),
  188. path,
  189. toError() {
  190. const error = new Error(this.message);
  191. error.code = this.code;
  192. if (this.path) {
  193. error.path = this.path;
  194. }
  195. return error;
  196. },
  197. };
  198. }
  199. //# sourceMappingURL=util.js.map