NodeFileSystemDirectoryHandle.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.NodeFileSystemDirectoryHandle = void 0;
  4. const NodeFileSystemHandle_1 = require("./NodeFileSystemHandle");
  5. const util_1 = require("./util");
  6. const NodeFileSystemFileHandle_1 = require("./NodeFileSystemFileHandle");
  7. /**
  8. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle
  9. */
  10. class NodeFileSystemDirectoryHandle extends NodeFileSystemHandle_1.NodeFileSystemHandle {
  11. constructor(fs, path, ctx = {}) {
  12. const fullCtx = (0, util_1.ctx)(ctx);
  13. super('directory', (0, util_1.basename)(path, fullCtx.separator));
  14. this.fs = fs;
  15. this.ctx = fullCtx;
  16. this.__path = path[path.length - 1] === this.ctx.separator ? path : path + this.ctx.separator;
  17. }
  18. /**
  19. * Returns a new array iterator containing the keys for each item in
  20. * {@link NodeFileSystemDirectoryHandle} object.
  21. *
  22. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/keys
  23. */
  24. async *keys() {
  25. const list = await this.fs.promises.readdir(this.__path);
  26. for (const name of list)
  27. yield '' + name;
  28. }
  29. /**
  30. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/entries
  31. */
  32. async *entries() {
  33. const { __path: path, fs, ctx } = this;
  34. const list = await fs.promises.readdir(path, { withFileTypes: true });
  35. for (const d of list) {
  36. const dirent = d;
  37. const name = dirent.name + '';
  38. const newPath = path + name;
  39. if (dirent.isDirectory())
  40. yield [name, new NodeFileSystemDirectoryHandle(fs, newPath, ctx)];
  41. else if (dirent.isFile())
  42. yield [name, new NodeFileSystemFileHandle_1.NodeFileSystemFileHandle(fs, newPath, ctx)];
  43. }
  44. }
  45. /**
  46. * Returns a new array iterator containing the values for each index in the
  47. * {@link FileSystemDirectoryHandle} object.
  48. *
  49. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/values
  50. */
  51. async *values() {
  52. for await (const [, value] of this.entries())
  53. yield value;
  54. }
  55. /**
  56. * Returns a {@link NodeFileSystemDirectoryHandle} for a subdirectory with the specified
  57. * name within the directory handle on which the method is called.
  58. *
  59. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/getDirectoryHandle
  60. * @param name A string representing the {@link NodeFileSystemHandle} name of
  61. * the subdirectory you wish to retrieve.
  62. * @param options An optional object containing options for the retrieved
  63. * subdirectory.
  64. */
  65. async getDirectoryHandle(name, options) {
  66. (0, util_1.assertName)(name, 'getDirectoryHandle', 'FileSystemDirectoryHandle');
  67. const filename = this.__path + name;
  68. try {
  69. const stats = await this.fs.promises.stat(filename);
  70. if (!stats.isDirectory())
  71. throw (0, util_1.newTypeMismatchError)();
  72. return new NodeFileSystemDirectoryHandle(this.fs, filename, this.ctx);
  73. }
  74. catch (error) {
  75. if (error instanceof DOMException)
  76. throw error;
  77. if (error && typeof error === 'object') {
  78. switch (error.code) {
  79. case 'ENOENT': {
  80. if (options?.create) {
  81. (0, util_1.assertCanWrite)(this.ctx.mode);
  82. await this.fs.promises.mkdir(filename);
  83. return new NodeFileSystemDirectoryHandle(this.fs, filename, this.ctx);
  84. }
  85. throw (0, util_1.newNotFoundError)();
  86. }
  87. case 'EPERM':
  88. case 'EACCES':
  89. throw (0, util_1.newNotAllowedError)();
  90. }
  91. }
  92. throw error;
  93. }
  94. }
  95. /**
  96. * Returns a {@link FileSystemFileHandle} for a file with the specified name,
  97. * within the directory the method is called.
  98. *
  99. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/getFileHandle
  100. * @param name A string representing the {@link NodeFileSystemHandle} name of
  101. * the file you wish to retrieve.
  102. * @param options An optional object containing options for the retrieved file.
  103. */
  104. async getFileHandle(name, options) {
  105. (0, util_1.assertName)(name, 'getFileHandle', 'FileSystemDirectoryHandle');
  106. const filename = this.__path + name;
  107. try {
  108. const stats = await this.fs.promises.stat(filename);
  109. if (!stats.isFile())
  110. throw (0, util_1.newTypeMismatchError)();
  111. return new NodeFileSystemFileHandle_1.NodeFileSystemFileHandle(this.fs, filename, this.ctx);
  112. }
  113. catch (error) {
  114. if (error instanceof DOMException)
  115. throw error;
  116. if (error && typeof error === 'object') {
  117. switch (error.code) {
  118. case 'ENOENT': {
  119. if (options?.create) {
  120. (0, util_1.assertCanWrite)(this.ctx.mode);
  121. await this.fs.promises.writeFile(filename, '');
  122. return new NodeFileSystemFileHandle_1.NodeFileSystemFileHandle(this.fs, filename, this.ctx);
  123. }
  124. throw (0, util_1.newNotFoundError)();
  125. }
  126. case 'EPERM':
  127. case 'EACCES':
  128. throw (0, util_1.newNotAllowedError)();
  129. }
  130. }
  131. throw error;
  132. }
  133. }
  134. /**
  135. * Attempts to remove an entry if the directory handle contains a file or
  136. * directory called the name specified.
  137. *
  138. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/removeEntry
  139. * @param name A string representing the {@link FileSystemHandle} name of the
  140. * entry you wish to remove.
  141. * @param options An optional object containing options.
  142. */
  143. async removeEntry(name, { recursive = false } = {}) {
  144. (0, util_1.assertCanWrite)(this.ctx.mode);
  145. (0, util_1.assertName)(name, 'removeEntry', 'FileSystemDirectoryHandle');
  146. const filename = this.__path + name;
  147. const promises = this.fs.promises;
  148. try {
  149. const stats = await promises.stat(filename);
  150. if (stats.isFile()) {
  151. await promises.unlink(filename);
  152. }
  153. else if (stats.isDirectory()) {
  154. await promises.rmdir(filename, { recursive });
  155. }
  156. else
  157. throw (0, util_1.newTypeMismatchError)();
  158. }
  159. catch (error) {
  160. if (error instanceof DOMException)
  161. throw error;
  162. if (error && typeof error === 'object') {
  163. switch (error.code) {
  164. case 'ENOENT': {
  165. throw (0, util_1.newNotFoundError)();
  166. }
  167. case 'EPERM':
  168. case 'EACCES':
  169. throw (0, util_1.newNotAllowedError)();
  170. case 'ENOTEMPTY':
  171. throw new DOMException('The object can not be modified in this way.', 'InvalidModificationError');
  172. }
  173. }
  174. throw error;
  175. }
  176. }
  177. /**
  178. * The `resolve()` method of the {@link FileSystemDirectoryHandle} interface
  179. * returns an {@link Array} of directory names from the parent handle to the specified
  180. * child entry, with the name of the child entry as the last array item.
  181. *
  182. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/resolve
  183. * @param possibleDescendant The {@link IFileSystemHandle} from which
  184. * to return the relative path.
  185. */
  186. async resolve(possibleDescendant) {
  187. if (possibleDescendant instanceof NodeFileSystemDirectoryHandle ||
  188. possibleDescendant instanceof NodeFileSystemFileHandle_1.NodeFileSystemFileHandle) {
  189. const path = this.__path;
  190. const childPath = possibleDescendant.__path;
  191. if (!childPath.startsWith(path))
  192. return null;
  193. let relative = childPath.slice(path.length);
  194. if (relative === '')
  195. return [];
  196. const separator = this.ctx.separator;
  197. if (relative[0] === separator)
  198. relative = relative.slice(1);
  199. return relative.split(separator);
  200. }
  201. return null;
  202. }
  203. }
  204. exports.NodeFileSystemDirectoryHandle = NodeFileSystemDirectoryHandle;
  205. //# sourceMappingURL=NodeFileSystemDirectoryHandle.js.map