NodeFileSystemDirectoryHandle.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. const { fs } = this;
  69. try {
  70. const stats = await fs.promises.stat(filename);
  71. if (!stats.isDirectory())
  72. throw (0, util_1.newTypeMismatchError)();
  73. return new NodeFileSystemDirectoryHandle(fs, filename, this.ctx);
  74. }
  75. catch (error) {
  76. if (error instanceof DOMException)
  77. throw error;
  78. if (error && typeof error === 'object') {
  79. switch (error.code) {
  80. case 'ENOENT': {
  81. if (options?.create) {
  82. (0, util_1.assertCanWrite)(this.ctx.mode);
  83. try {
  84. await fs.promises.mkdir(filename);
  85. }
  86. catch (mkdirError) {
  87. if (mkdirError && typeof mkdirError === 'object' && mkdirError.code === 'EEXIST') {
  88. const stats = await fs.promises.stat(filename);
  89. if (!stats.isDirectory())
  90. throw (0, util_1.newTypeMismatchError)();
  91. return new NodeFileSystemDirectoryHandle(fs, filename, this.ctx);
  92. }
  93. throw mkdirError;
  94. }
  95. return new NodeFileSystemDirectoryHandle(fs, filename, this.ctx);
  96. }
  97. throw (0, util_1.newNotFoundError)();
  98. }
  99. case 'EPERM':
  100. case 'EACCES':
  101. throw (0, util_1.newNotAllowedError)();
  102. }
  103. }
  104. throw error;
  105. }
  106. }
  107. /**
  108. * Returns a {@link FileSystemFileHandle} for a file with the specified name,
  109. * within the directory the method is called.
  110. *
  111. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/getFileHandle
  112. * @param name A string representing the {@link NodeFileSystemHandle} name of
  113. * the file you wish to retrieve.
  114. * @param options An optional object containing options for the retrieved file.
  115. */
  116. async getFileHandle(name, options) {
  117. (0, util_1.assertName)(name, 'getFileHandle', 'FileSystemDirectoryHandle');
  118. const filename = this.__path + name;
  119. try {
  120. const stats = await this.fs.promises.stat(filename);
  121. if (!stats.isFile())
  122. throw (0, util_1.newTypeMismatchError)();
  123. return new NodeFileSystemFileHandle_1.NodeFileSystemFileHandle(this.fs, filename, this.ctx);
  124. }
  125. catch (error) {
  126. if (error instanceof DOMException)
  127. throw error;
  128. if (error && typeof error === 'object') {
  129. switch (error.code) {
  130. case 'ENOENT': {
  131. if (options?.create) {
  132. (0, util_1.assertCanWrite)(this.ctx.mode);
  133. await this.fs.promises.writeFile(filename, '');
  134. return new NodeFileSystemFileHandle_1.NodeFileSystemFileHandle(this.fs, filename, this.ctx);
  135. }
  136. throw (0, util_1.newNotFoundError)();
  137. }
  138. case 'EPERM':
  139. case 'EACCES':
  140. throw (0, util_1.newNotAllowedError)();
  141. }
  142. }
  143. throw error;
  144. }
  145. }
  146. /**
  147. * Attempts to remove an entry if the directory handle contains a file or
  148. * directory called the name specified.
  149. *
  150. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/removeEntry
  151. * @param name A string representing the {@link FileSystemHandle} name of the
  152. * entry you wish to remove.
  153. * @param options An optional object containing options.
  154. */
  155. async removeEntry(name, { recursive = false } = {}) {
  156. (0, util_1.assertCanWrite)(this.ctx.mode);
  157. (0, util_1.assertName)(name, 'removeEntry', 'FileSystemDirectoryHandle');
  158. const filename = this.__path + name;
  159. const promises = this.fs.promises;
  160. try {
  161. const stats = await promises.stat(filename);
  162. if (stats.isFile()) {
  163. await promises.unlink(filename);
  164. }
  165. else if (stats.isDirectory()) {
  166. await promises.rmdir(filename, { recursive });
  167. }
  168. else
  169. throw (0, util_1.newTypeMismatchError)();
  170. }
  171. catch (error) {
  172. if (error instanceof DOMException)
  173. throw error;
  174. if (error && typeof error === 'object') {
  175. switch (error.code) {
  176. case 'ENOENT': {
  177. throw (0, util_1.newNotFoundError)();
  178. }
  179. case 'EPERM':
  180. case 'EACCES':
  181. throw (0, util_1.newNotAllowedError)();
  182. case 'ENOTEMPTY':
  183. throw new DOMException('The object can not be modified in this way.', 'InvalidModificationError');
  184. }
  185. }
  186. throw error;
  187. }
  188. }
  189. /**
  190. * The `resolve()` method of the {@link FileSystemDirectoryHandle} interface
  191. * returns an {@link Array} of directory names from the parent handle to the specified
  192. * child entry, with the name of the child entry as the last array item.
  193. *
  194. * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/resolve
  195. * @param possibleDescendant The {@link IFileSystemHandle} from which
  196. * to return the relative path.
  197. */
  198. async resolve(possibleDescendant) {
  199. if (possibleDescendant instanceof NodeFileSystemDirectoryHandle ||
  200. possibleDescendant instanceof NodeFileSystemFileHandle_1.NodeFileSystemFileHandle) {
  201. const path = this.__path;
  202. const childPath = possibleDescendant.__path;
  203. if (!childPath.startsWith(path))
  204. return null;
  205. let relative = childPath.slice(path.length);
  206. if (relative === '')
  207. return [];
  208. const separator = this.ctx.separator;
  209. if (relative[0] === separator)
  210. relative = relative.slice(1);
  211. return relative.split(separator);
  212. }
  213. return null;
  214. }
  215. }
  216. exports.NodeFileSystemDirectoryHandle = NodeFileSystemDirectoryHandle;
  217. //# sourceMappingURL=NodeFileSystemDirectoryHandle.js.map