util.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.unixify = exports.getWriteSyncArgs = exports.getWriteArgs = exports.bufToUint8 = exports.isWin = void 0;
  4. exports.promisify = promisify;
  5. exports.validateCallback = validateCallback;
  6. exports.modeToNumber = modeToNumber;
  7. exports.nullCheck = nullCheck;
  8. exports.pathToFilename = pathToFilename;
  9. exports.createError = createError;
  10. exports.genRndStr6 = genRndStr6;
  11. exports.flagsToNumber = flagsToNumber;
  12. exports.isFd = isFd;
  13. exports.validateFd = validateFd;
  14. exports.dataToBuffer = dataToBuffer;
  15. exports.bufferToEncoding = bufferToEncoding;
  16. const constants_1 = require("./constants");
  17. const errors = require("../internal/errors");
  18. const buffer_1 = require("../internal/buffer");
  19. const encoding_1 = require("../encoding");
  20. const buffer_2 = require("../internal/buffer");
  21. const queueMicrotask_1 = require("../queueMicrotask");
  22. exports.isWin = process.platform === 'win32';
  23. function promisify(fs, fn, getResult = input => input) {
  24. return (...args) => new Promise((resolve, reject) => {
  25. fs[fn].bind(fs)(...args, (error, result) => {
  26. if (error)
  27. return reject(error);
  28. return resolve(getResult(result));
  29. });
  30. });
  31. }
  32. function validateCallback(callback) {
  33. if (typeof callback !== 'function')
  34. throw TypeError(constants_1.ERRSTR.CB);
  35. return callback;
  36. }
  37. function _modeToNumber(mode, def) {
  38. if (typeof mode === 'number')
  39. return mode;
  40. if (typeof mode === 'string')
  41. return parseInt(mode, 8);
  42. if (def)
  43. return modeToNumber(def);
  44. return undefined;
  45. }
  46. function modeToNumber(mode, def) {
  47. const result = _modeToNumber(mode, def);
  48. if (typeof result !== 'number' || isNaN(result))
  49. throw new TypeError(constants_1.ERRSTR.MODE_INT);
  50. return result;
  51. }
  52. function nullCheck(path, callback) {
  53. if (('' + path).indexOf('\u0000') !== -1) {
  54. const er = new Error('Path must be a string without null bytes');
  55. er.code = 'ENOENT';
  56. if (typeof callback !== 'function')
  57. throw er;
  58. (0, queueMicrotask_1.default)(() => {
  59. callback(er);
  60. });
  61. return false;
  62. }
  63. return true;
  64. }
  65. function getPathFromURLPosix(url) {
  66. if (url.hostname !== '') {
  67. throw new errors.TypeError('ERR_INVALID_FILE_URL_HOST', process.platform);
  68. }
  69. const pathname = url.pathname;
  70. for (let n = 0; n < pathname.length; n++) {
  71. if (pathname[n] === '%') {
  72. const third = pathname.codePointAt(n + 2) | 0x20;
  73. if (pathname[n + 1] === '2' && third === 102) {
  74. throw new errors.TypeError('ERR_INVALID_FILE_URL_PATH', 'must not include encoded / characters');
  75. }
  76. }
  77. }
  78. return decodeURIComponent(pathname);
  79. }
  80. function pathToFilename(path) {
  81. if (typeof path !== 'string' && !buffer_1.Buffer.isBuffer(path)) {
  82. try {
  83. if (!(path instanceof require('url').URL))
  84. throw new TypeError(constants_1.ERRSTR.PATH_STR);
  85. }
  86. catch (err) {
  87. throw new TypeError(constants_1.ERRSTR.PATH_STR);
  88. }
  89. path = getPathFromURLPosix(path);
  90. }
  91. const pathString = String(path);
  92. nullCheck(pathString);
  93. // return slash(pathString);
  94. return pathString;
  95. }
  96. const ENOENT = 'ENOENT';
  97. const EBADF = 'EBADF';
  98. const EINVAL = 'EINVAL';
  99. const EPERM = 'EPERM';
  100. const EPROTO = 'EPROTO';
  101. const EEXIST = 'EEXIST';
  102. const ENOTDIR = 'ENOTDIR';
  103. const EMFILE = 'EMFILE';
  104. const EACCES = 'EACCES';
  105. const EISDIR = 'EISDIR';
  106. const ENOTEMPTY = 'ENOTEMPTY';
  107. const ENOSYS = 'ENOSYS';
  108. const ERR_FS_EISDIR = 'ERR_FS_EISDIR';
  109. const ERR_OUT_OF_RANGE = 'ERR_OUT_OF_RANGE';
  110. function formatError(errorCode, func = '', path = '', path2 = '') {
  111. let pathFormatted = '';
  112. if (path)
  113. pathFormatted = ` '${path}'`;
  114. if (path2)
  115. pathFormatted += ` -> '${path2}'`;
  116. switch (errorCode) {
  117. case ENOENT:
  118. return `ENOENT: no such file or directory, ${func}${pathFormatted}`;
  119. case EBADF:
  120. return `EBADF: bad file descriptor, ${func}${pathFormatted}`;
  121. case EINVAL:
  122. return `EINVAL: invalid argument, ${func}${pathFormatted}`;
  123. case EPERM:
  124. return `EPERM: operation not permitted, ${func}${pathFormatted}`;
  125. case EPROTO:
  126. return `EPROTO: protocol error, ${func}${pathFormatted}`;
  127. case EEXIST:
  128. return `EEXIST: file already exists, ${func}${pathFormatted}`;
  129. case ENOTDIR:
  130. return `ENOTDIR: not a directory, ${func}${pathFormatted}`;
  131. case EISDIR:
  132. return `EISDIR: illegal operation on a directory, ${func}${pathFormatted}`;
  133. case EACCES:
  134. return `EACCES: permission denied, ${func}${pathFormatted}`;
  135. case ENOTEMPTY:
  136. return `ENOTEMPTY: directory not empty, ${func}${pathFormatted}`;
  137. case EMFILE:
  138. return `EMFILE: too many open files, ${func}${pathFormatted}`;
  139. case ENOSYS:
  140. return `ENOSYS: function not implemented, ${func}${pathFormatted}`;
  141. case ERR_FS_EISDIR:
  142. return `[ERR_FS_EISDIR]: Path is a directory: ${func} returned EISDIR (is a directory) ${path}`;
  143. case ERR_OUT_OF_RANGE:
  144. return `[ERR_OUT_OF_RANGE]: value out of range, ${func}${pathFormatted}`;
  145. default:
  146. return `${errorCode}: error occurred, ${func}${pathFormatted}`;
  147. }
  148. }
  149. function createError(errorCode, func = '', path = '', path2 = '', Constructor = Error) {
  150. const error = new Constructor(formatError(errorCode, func, path, path2));
  151. error.code = errorCode;
  152. if (path) {
  153. error.path = path;
  154. }
  155. return error;
  156. }
  157. function genRndStr6() {
  158. const str = (Math.random() + 1).toString(36).substring(2, 8);
  159. if (str.length === 6)
  160. return str;
  161. else
  162. return genRndStr6();
  163. }
  164. function flagsToNumber(flags) {
  165. if (typeof flags === 'number')
  166. return flags;
  167. if (typeof flags === 'string') {
  168. const flagsNum = constants_1.FLAGS[flags];
  169. if (typeof flagsNum !== 'undefined')
  170. return flagsNum;
  171. }
  172. // throw new TypeError(formatError(ERRSTR_FLAG(flags)));
  173. throw new errors.TypeError('ERR_INVALID_OPT_VALUE', 'flags', flags);
  174. }
  175. function isFd(path) {
  176. return path >>> 0 === path;
  177. }
  178. function validateFd(fd) {
  179. if (!isFd(fd))
  180. throw TypeError(constants_1.ERRSTR.FD);
  181. }
  182. function dataToBuffer(data, encoding = encoding_1.ENCODING_UTF8) {
  183. if (buffer_1.Buffer.isBuffer(data))
  184. return data;
  185. else if (data instanceof Uint8Array)
  186. return (0, buffer_2.bufferFrom)(data);
  187. else
  188. return (0, buffer_2.bufferFrom)(String(data), encoding);
  189. }
  190. const bufToUint8 = (buf) => new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
  191. exports.bufToUint8 = bufToUint8;
  192. const getWriteArgs = (fd, a, b, c, d, e) => {
  193. validateFd(fd);
  194. let offset = 0;
  195. let length;
  196. let position = null;
  197. let encoding;
  198. let callback;
  199. const tipa = typeof a;
  200. const tipb = typeof b;
  201. const tipc = typeof c;
  202. const tipd = typeof d;
  203. if (tipa !== 'string') {
  204. if (tipb === 'function') {
  205. callback = b;
  206. }
  207. else if (tipc === 'function') {
  208. offset = b | 0;
  209. callback = c;
  210. }
  211. else if (tipd === 'function') {
  212. offset = b | 0;
  213. length = c;
  214. callback = d;
  215. }
  216. else {
  217. offset = b | 0;
  218. length = c;
  219. position = d;
  220. callback = e;
  221. }
  222. }
  223. else {
  224. if (tipb === 'function') {
  225. callback = b;
  226. }
  227. else if (tipc === 'function') {
  228. position = b;
  229. callback = c;
  230. }
  231. else if (tipd === 'function') {
  232. position = b;
  233. encoding = c;
  234. callback = d;
  235. }
  236. }
  237. const buf = dataToBuffer(a, encoding);
  238. if (tipa !== 'string') {
  239. if (typeof length === 'undefined')
  240. length = buf.length;
  241. }
  242. else {
  243. offset = 0;
  244. length = buf.length;
  245. }
  246. const cb = validateCallback(callback);
  247. return [fd, tipa === 'string', buf, offset, length, position, cb];
  248. };
  249. exports.getWriteArgs = getWriteArgs;
  250. const getWriteSyncArgs = (fd, a, b, c, d) => {
  251. validateFd(fd);
  252. let encoding;
  253. let offset;
  254. let length;
  255. let position;
  256. const isBuffer = typeof a !== 'string';
  257. if (isBuffer) {
  258. offset = (b || 0) | 0;
  259. length = c;
  260. position = d;
  261. }
  262. else {
  263. position = b;
  264. encoding = c;
  265. }
  266. const buf = dataToBuffer(a, encoding);
  267. if (isBuffer) {
  268. if (typeof length === 'undefined') {
  269. length = buf.length;
  270. }
  271. }
  272. else {
  273. offset = 0;
  274. length = buf.length;
  275. }
  276. return [fd, buf, offset || 0, length, position];
  277. };
  278. exports.getWriteSyncArgs = getWriteSyncArgs;
  279. function bufferToEncoding(buffer, encoding) {
  280. if (!encoding || encoding === 'buffer')
  281. return buffer;
  282. else
  283. return buffer.toString(encoding);
  284. }
  285. const isSeparator = (str, i) => {
  286. let char = str[i];
  287. return i > 0 && (char === '/' || (exports.isWin && char === '\\'));
  288. };
  289. const removeTrailingSeparator = (str) => {
  290. let i = str.length - 1;
  291. if (i < 2)
  292. return str;
  293. while (isSeparator(str, i))
  294. i--;
  295. return str.substr(0, i + 1);
  296. };
  297. const normalizePath = (str, stripTrailing) => {
  298. if (typeof str !== 'string')
  299. throw new TypeError('expected a string');
  300. str = str.replace(/[\\\/]+/g, '/');
  301. if (stripTrailing !== false)
  302. str = removeTrailingSeparator(str);
  303. return str;
  304. };
  305. const unixify = (filepath, stripTrailing = true) => {
  306. if (exports.isWin) {
  307. filepath = normalizePath(filepath, stripTrailing);
  308. return filepath.replace(/^([a-zA-Z]+:|\.\/)/, '');
  309. }
  310. return filepath;
  311. };
  312. exports.unixify = unixify;
  313. //# sourceMappingURL=util.js.map