FileHandle.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. "use strict";
  2. var _a, _b, _c, _d;
  3. Object.defineProperty(exports, "__esModule", { value: true });
  4. exports.FileHandle = void 0;
  5. const readline_1 = require("readline");
  6. const kBaseFs = Symbol(`kBaseFs`);
  7. const kFd = Symbol(`kFd`);
  8. const kClosePromise = Symbol(`kClosePromise`);
  9. const kCloseResolve = Symbol(`kCloseResolve`);
  10. const kCloseReject = Symbol(`kCloseReject`);
  11. const kRefs = Symbol(`kRefs`);
  12. const kRef = Symbol(`kRef`);
  13. const kUnref = Symbol(`kUnref`);
  14. class FileHandle {
  15. constructor(fd, baseFs) {
  16. this[_a] = 1;
  17. this[_b] = undefined;
  18. this[_c] = undefined;
  19. this[_d] = undefined;
  20. this[kBaseFs] = baseFs;
  21. this[kFd] = fd;
  22. }
  23. get fd() {
  24. return this[kFd];
  25. }
  26. async appendFile(data, options) {
  27. var _e;
  28. try {
  29. this[kRef](this.appendFile);
  30. const encoding = (_e = (typeof options === `string` ? options : options === null || options === void 0 ? void 0 : options.encoding)) !== null && _e !== void 0 ? _e : undefined;
  31. return await this[kBaseFs].appendFilePromise(this.fd, data, encoding ? { encoding } : undefined);
  32. }
  33. finally {
  34. this[kUnref]();
  35. }
  36. }
  37. async chown(uid, gid) {
  38. try {
  39. this[kRef](this.chown);
  40. return await this[kBaseFs].fchownPromise(this.fd, uid, gid);
  41. }
  42. finally {
  43. this[kUnref]();
  44. }
  45. }
  46. async chmod(mode) {
  47. try {
  48. this[kRef](this.chmod);
  49. return await this[kBaseFs].fchmodPromise(this.fd, mode);
  50. }
  51. finally {
  52. this[kUnref]();
  53. }
  54. }
  55. createReadStream(options) {
  56. return this[kBaseFs].createReadStream(null, { ...options, fd: this.fd });
  57. }
  58. createWriteStream(options) {
  59. return this[kBaseFs].createWriteStream(null, { ...options, fd: this.fd });
  60. }
  61. // FIXME: Missing FakeFS version
  62. datasync() {
  63. throw new Error(`Method not implemented.`);
  64. }
  65. // FIXME: Missing FakeFS version
  66. sync() {
  67. throw new Error(`Method not implemented.`);
  68. }
  69. async read(bufferOrOptions, offset, length, position) {
  70. var _e, _f, _g;
  71. try {
  72. this[kRef](this.read);
  73. let buffer;
  74. if (!Buffer.isBuffer(bufferOrOptions)) {
  75. bufferOrOptions !== null && bufferOrOptions !== void 0 ? bufferOrOptions : (bufferOrOptions = {});
  76. buffer = (_e = bufferOrOptions.buffer) !== null && _e !== void 0 ? _e : Buffer.alloc(16384);
  77. offset = bufferOrOptions.offset || 0;
  78. length = (_f = bufferOrOptions.length) !== null && _f !== void 0 ? _f : buffer.byteLength;
  79. position = (_g = bufferOrOptions.position) !== null && _g !== void 0 ? _g : null;
  80. }
  81. else {
  82. buffer = bufferOrOptions;
  83. }
  84. offset !== null && offset !== void 0 ? offset : (offset = 0);
  85. length !== null && length !== void 0 ? length : (length = 0);
  86. if (length === 0) {
  87. return {
  88. bytesRead: length,
  89. buffer,
  90. };
  91. }
  92. const bytesRead = await this[kBaseFs].readPromise(this.fd, buffer, offset, length, position);
  93. return {
  94. bytesRead,
  95. buffer,
  96. };
  97. }
  98. finally {
  99. this[kUnref]();
  100. }
  101. }
  102. async readFile(options) {
  103. var _e;
  104. try {
  105. this[kRef](this.readFile);
  106. const encoding = (_e = (typeof options === `string` ? options : options === null || options === void 0 ? void 0 : options.encoding)) !== null && _e !== void 0 ? _e : undefined;
  107. return await this[kBaseFs].readFilePromise(this.fd, encoding);
  108. }
  109. finally {
  110. this[kUnref]();
  111. }
  112. }
  113. readLines(options) {
  114. return (0, readline_1.createInterface)({
  115. input: this.createReadStream(options),
  116. crlfDelay: Infinity,
  117. });
  118. }
  119. async stat(opts) {
  120. try {
  121. this[kRef](this.stat);
  122. return await this[kBaseFs].fstatPromise(this.fd, opts);
  123. }
  124. finally {
  125. this[kUnref]();
  126. }
  127. }
  128. async truncate(len) {
  129. try {
  130. this[kRef](this.truncate);
  131. return await this[kBaseFs].ftruncatePromise(this.fd, len);
  132. }
  133. finally {
  134. this[kUnref]();
  135. }
  136. }
  137. // FIXME: Missing FakeFS version
  138. utimes(atime, mtime) {
  139. throw new Error(`Method not implemented.`);
  140. }
  141. async writeFile(data, options) {
  142. var _e;
  143. try {
  144. this[kRef](this.writeFile);
  145. const encoding = (_e = (typeof options === `string` ? options : options === null || options === void 0 ? void 0 : options.encoding)) !== null && _e !== void 0 ? _e : undefined;
  146. await this[kBaseFs].writeFilePromise(this.fd, data, encoding);
  147. }
  148. finally {
  149. this[kUnref]();
  150. }
  151. }
  152. async write(...args) {
  153. try {
  154. this[kRef](this.write);
  155. if (ArrayBuffer.isView(args[0])) {
  156. const [buffer, offset, length, position] = args;
  157. const bytesWritten = await this[kBaseFs].writePromise(this.fd, buffer, offset !== null && offset !== void 0 ? offset : undefined, length !== null && length !== void 0 ? length : undefined, position !== null && position !== void 0 ? position : undefined);
  158. return { bytesWritten, buffer };
  159. }
  160. else {
  161. const [data, position, encoding] = args;
  162. // @ts-expect-error - FIXME: Types/implementation need to be updated in FakeFS
  163. const bytesWritten = await this[kBaseFs].writePromise(this.fd, data, position, encoding);
  164. return { bytesWritten, buffer: data };
  165. }
  166. }
  167. finally {
  168. this[kUnref]();
  169. }
  170. }
  171. // TODO: Use writev from FakeFS when that is implemented
  172. async writev(buffers, position) {
  173. try {
  174. this[kRef](this.writev);
  175. let bytesWritten = 0;
  176. if (typeof position !== `undefined`) {
  177. for (const buffer of buffers) {
  178. const writeResult = await this.write(buffer, undefined, undefined, position);
  179. bytesWritten += writeResult.bytesWritten;
  180. position += writeResult.bytesWritten;
  181. }
  182. }
  183. else {
  184. for (const buffer of buffers) {
  185. const writeResult = await this.write(buffer);
  186. bytesWritten += writeResult.bytesWritten;
  187. }
  188. }
  189. return {
  190. buffers,
  191. bytesWritten,
  192. };
  193. }
  194. finally {
  195. this[kUnref]();
  196. }
  197. }
  198. // FIXME: Missing FakeFS version
  199. readv(buffers, position) {
  200. throw new Error(`Method not implemented.`);
  201. }
  202. close() {
  203. if (this[kFd] === -1)
  204. return Promise.resolve();
  205. if (this[kClosePromise])
  206. return this[kClosePromise];
  207. this[kRefs]--;
  208. if (this[kRefs] === 0) {
  209. const fd = this[kFd];
  210. this[kFd] = -1;
  211. this[kClosePromise] = this[kBaseFs].closePromise(fd).finally(() => {
  212. this[kClosePromise] = undefined;
  213. });
  214. }
  215. else {
  216. this[kClosePromise] =
  217. new Promise((resolve, reject) => {
  218. this[kCloseResolve] = resolve;
  219. this[kCloseReject] = reject;
  220. }).finally(() => {
  221. this[kClosePromise] = undefined;
  222. this[kCloseReject] = undefined;
  223. this[kCloseResolve] = undefined;
  224. });
  225. }
  226. return this[kClosePromise];
  227. }
  228. [(_a = kRefs, _b = kClosePromise, _c = kCloseResolve, _d = kCloseReject, kRef)](caller) {
  229. if (this[kFd] === -1) {
  230. const err = new Error(`file closed`);
  231. err.code = `EBADF`;
  232. err.syscall = caller.name;
  233. throw err;
  234. }
  235. this[kRefs]++;
  236. }
  237. [kUnref]() {
  238. this[kRefs]--;
  239. if (this[kRefs] === 0) {
  240. const fd = this[kFd];
  241. this[kFd] = -1;
  242. this[kBaseFs].closePromise(fd).then(this[kCloseResolve], this[kCloseReject]);
  243. }
  244. }
  245. }
  246. exports.FileHandle = FileHandle;