Source

fs-file.class.ts

  1. import { stat, Stats, access, constants, unlink, copyFile, rename } from 'fs';
  2. import { basename, dirname } from 'path';
  3. import { FSFileWrite } from './fs-file.write.class';
  4. import { FSFileRead } from './fs-file.read.class';
  5. import { FSDir } from './fs-dir.class';
  6. import { FSFileHash } from './fs-file.hash.class';
  7. /**
  8. * Options that specifies the behavior of the copyTo operation
  9. */
  10. export type copyToOptions = {
  11. /**
  12. * If true, then the copy operation will fail if dest already exists.
  13. * COPYFILE_FICLONE_FORCE: The copy operation will attempt to create a
  14. * copy-on-write reflink. If the platform does not support copy-on-write, then the operation will fail.
  15. */
  16. COPYFILE_EXCL?: boolean;
  17. /**
  18. * If true then the copy operation will attempt to create a copy-on-write reflink.
  19. * If the platform does not support copy-on-write, then a fallback copy mechanism is used.
  20. */
  21. COPYFILE_FICLONE?: boolean;
  22. /**
  23. * If true then the copy operation will attempt to create a copy-on-write reflink.
  24. * If the platform does not support copy-on-write, then a fallback copy mechanism is used.
  25. */
  26. COPYFILE_FICLONE_FORCE?: boolean;
  27. };
  28. /**
  29. * Contains all methods to work with files.
  30. */
  31. export class FSFile {
  32. constructor(public readonly path: string) {}
  33. /**
  34. * Contains file name.
  35. */
  36. public readonly name = basename(this.path);
  37. /**
  38. * Returns directory wich contains this file
  39. * @type {FSDir}
  40. */
  41. public readonly fsdir: FSDir = new FSDir(dirname(this.path));
  42. /**
  43. * Contains all methods for file read.
  44. * @type {FSFileRead}
  45. */
  46. public read: FSFileRead = new FSFileRead(this.path);
  47. /**
  48. * Contains all methods for writing file
  49. * @type {FSFileWrite}
  50. */
  51. public write: FSFileWrite = new FSFileWrite(this.path);
  52. /**
  53. *
  54. */
  55. public hash: FSFileHash = new FSFileHash(this.path);
  56. /**
  57. * Returns file Stats object
  58. * @
  59. * @returns {Promise<Stats>}
  60. */
  61. public async stat(): Promise<Stats> {
  62. return new Promise<Stats>((resolve, reject) => {
  63. stat(this.path, (err, stat) => {
  64. if (err) return reject(err);
  65. resolve(stat);
  66. });
  67. });
  68. }
  69. /**
  70. * Checks is file exits. If you need write or read file
  71. * use isWritable or isReadable to check if it possible.
  72. */
  73. public async isExists() {
  74. return new Promise<boolean>(resolve => {
  75. access(this.path, constants.F_OK, err => {
  76. if (err) return resolve(false);
  77. resolve(true);
  78. });
  79. });
  80. }
  81. /**
  82. * Checks possibility to read file.
  83. */
  84. public async isReadable() {
  85. return new Promise<boolean>(resolve => {
  86. access(this.path, constants.R_OK, err => {
  87. if (err) return resolve(false);
  88. resolve(true);
  89. });
  90. });
  91. }
  92. /**
  93. * Checks possibility to write into file.
  94. */
  95. public async isWritable() {
  96. return new Promise<boolean>(resolve => {
  97. access(this.path, constants.W_OK, err => {
  98. if (err) return resolve(false);
  99. resolve(true);
  100. });
  101. });
  102. }
  103. /**
  104. * Asynchronously removes a file.
  105. */
  106. public async unlink() {
  107. return new Promise<void>((resolve, reject) => {
  108. unlink(this.path, err => {
  109. if (err) return reject(err);
  110. resolve();
  111. });
  112. });
  113. }
  114. /**
  115. * Copy file. If dest is FSDir, copy file in it with source name.
  116. * @param {string | FSDir | FSFile} dest
  117. * @param {copyToOptions} options is an optional parameter that specifies the behavior of the copy operation.
  118. * COPYFILE_EXCL: The copy operation will fail if dest already exists.
  119. * COPYFILE_FICLONE: The copy operation will attempt to create a copy-on-write reflink.
  120. * If the platform does not support copy-on-write, then a fallback copy mechanism is used.
  121. * COPYFILE_FICLONE_FORCE: The copy operation will attempt to create a
  122. * copy-on-write reflink. If the platform does not support copy-on-write, then the operation will fail.
  123. * @returns {Promise<FSFile>} return FSFile of destination file
  124. */
  125. public async copyTo(dest: string | FSDir | FSFile, options: copyToOptions = {}): Promise<FSFile> {
  126. let destPath: string;
  127. if (typeof dest === 'string') {
  128. destPath = dest;
  129. } else if (dest instanceof FSDir) {
  130. destPath = dest.fspath[this.name]().path;
  131. } else if (dest instanceof FSFile) {
  132. destPath = dest.path;
  133. } else {
  134. throw Error("Wrong 'dest' argument. Must be string or FSDir or FSFile.");
  135. }
  136. const flags =
  137. (options.COPYFILE_EXCL ? constants.COPYFILE_EXCL : 0) |
  138. (options.COPYFILE_FICLONE ? constants.COPYFILE_FICLONE : 0) |
  139. (options.COPYFILE_FICLONE_FORCE ? constants.COPYFILE_FICLONE_FORCE : 0);
  140. return new Promise<FSFile>((resolve, reject) => {
  141. copyFile(this.path, destPath, flags, err => {
  142. if (err) return reject(err);
  143. if (dest instanceof FSFile) {
  144. resolve(dest);
  145. } else {
  146. resolve(new FSFile(destPath));
  147. }
  148. });
  149. });
  150. }
  151. /**
  152. * Moves file to destination directory
  153. * @param {FSDir} destDir - destination directory
  154. * @returns {Promise<FSFile>} - destination file
  155. */
  156. public async moveTo(destDir: FSDir): Promise<FSFile> {
  157. return new Promise<FSFile>((resolve, reject) => {
  158. const dest = destDir.fspath[this.name]().asFile();
  159. rename(dest.path, destDir.path, err => {
  160. if (err) return reject(err);
  161. resolve(dest);
  162. });
  163. });
  164. }
  165. /**
  166. * Rename file to target
  167. * @param {string} targetName - name of target file
  168. * @returns {Promise<FSFile>} - renamed file
  169. */
  170. public async rename(targetName: string): Promise<FSFile> {
  171. const targetFile = this.fsdir.fspath[targetName]().asFile();
  172. return new Promise<FSFile>((resolve, reject) => {
  173. rename(this.path, targetFile.path, err => {
  174. if (err) return reject(err);
  175. resolve(targetFile);
  176. });
  177. });
  178. }
  179. }