All files / src/node-to-fsa NodeFileSystemFileHandle.ts

75.86% Statements 22/29
10% Branches 1/10
100% Functions 5/5
80.76% Lines 21/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 7110x 10x 10x 10x       10x       1739x 1739x     1739x 1739x 1739x                   617x 617x 617x 617x   617x 617x 617x                                   12x 12x                 1007x 1005x              
import { NodeFileSystemHandle } from './NodeFileSystemHandle';
import { NodeFileSystemSyncAccessHandle } from './NodeFileSystemSyncAccessHandle';
import { assertCanWrite, basename, ctx as createCtx, newNotAllowedError } from './util';
import { NodeFileSystemWritableFileStream } from './NodeFileSystemWritableFileStream';
import type { NodeFsaContext, NodeFsaFs } from './types';
import type { IFileSystemFileHandle, IFileSystemSyncAccessHandle } from '../fsa/types';
 
export class NodeFileSystemFileHandle extends NodeFileSystemHandle implements IFileSystemFileHandle {
  protected readonly ctx: NodeFsaContext;
 
  constructor(
    protected readonly fs: NodeFsaFs,
    public readonly __path: string,
    ctx: Partial<NodeFsaContext> = {},
  ) {
    ctx = createCtx(ctx);
    super('file', basename(__path, ctx.separator!));
    this.ctx = ctx as NodeFsaContext;
  }
 
  /**
   * Returns a {@link Promise} which resolves to a {@link File} object
   * representing the state on disk of the entry represented by the handle.
   *
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/getFile
   */
  public async getFile(): Promise<File> {
    try {
      const path = this.__path;
      const promises = this.fs.promises;
      const stats = await promises.stat(path);
      // TODO: Once implemented, use promises.readAsBlob() instead of promises.readFile().
      const data = await promises.readFile(path);
      const file = new File([data], this.name, { lastModified: stats.mtime.getTime() });
      return file;
    } catch (error) {
      Iif (error instanceof DOMException) throw error;
      Iif (error && typeof error === 'object') {
        switch (error.code) {
          case 'EPERM':
          case 'EACCES':
            throw newNotAllowedError();
        }
      }
      throw error;
    }
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createSyncAccessHandle
   */
  public get createSyncAccessHandle(): undefined | (() => Promise<IFileSystemSyncAccessHandle>) {
    Iif (!this.ctx.syncHandleAllowed) return undefined;
    return async () => new NodeFileSystemSyncAccessHandle(this.fs, this.__path, this.ctx);
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createWritable
   */
  public async createWritable(
    { keepExistingData = false }: CreateWritableOptions = { keepExistingData: false },
  ): Promise<NodeFileSystemWritableFileStream> {
    assertCanWrite(this.ctx.mode);
    return new NodeFileSystemWritableFileStream(this.fs, this.__path, keepExistingData);
  }
}
 
export interface CreateWritableOptions {
  keepExistingData?: boolean;
}