util.js 9.0 KB

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