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

90.47% Statements 19/21
88.88% Branches 8/9
60% Functions 3/5
90.47% Lines 19/21

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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 866x                     6x           387x 387x                 7x                     10x     10x 10x     10x 2x     8x   8x   8x 5x 3x 3x       8x   7x     1x                                        
import { NodePermissionStatus } from './NodePermissionStatus';
import { AMODE } from '../consts/AMODE';
import type { IFileSystemHandle, FileSystemHandlePermissionDescriptor } from '../fsa/types';
import type { NodeFsaFs, NodeFsaContext } from './types';
 
/**
 * Represents a File System Access API file handle `FileSystemHandle` object,
 * which was created from a Node.js `fs` module.
 *
 * @see [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle)
 */
export abstract class NodeFileSystemHandle implements IFileSystemHandle {
  protected abstract readonly fs: NodeFsaFs;
  protected abstract readonly __path: string;
  protected abstract readonly ctx: NodeFsaContext;
 
  constructor(
    public readonly kind: 'file' | 'directory',
    public readonly name: string,
  ) {}
 
  /**
   * Compares two handles to see if the associated entries (either a file or directory) match.
   *
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle/isSameEntry
   */
  public isSameEntry(fileSystemHandle: IFileSystemHandle): boolean {
    return (
      this.constructor === fileSystemHandle.constructor && (this as any).__path === (fileSystemHandle as any).__path
    );
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle/queryPermission
   */
  public async queryPermission(
    fileSystemHandlePermissionDescriptor: FileSystemHandlePermissionDescriptor,
  ): Promise<NodePermissionStatus> {
    const { mode } = fileSystemHandlePermissionDescriptor;
 
    // Check if the requested mode is compatible with the context mode
    const requestedMode = mode;
    const contextMode = this.ctx.mode;
 
    // If requesting readwrite but context only allows read, deny
    if (requestedMode === 'readwrite' && contextMode === 'read') {
      return new NodePermissionStatus(requestedMode, 'denied');
    }
 
    try {
      // Use Node.js fs.promises.access() to check permissions asynchronously
      let accessMode = AMODE.F_OK;
 
      if (mode === 'read') {
        accessMode = AMODE.R_OK;
      } else if (mode === 'readwrite') {
        accessMode = AMODE.R_OK | AMODE.W_OK;
      }
 
      // Use asynchronous access check
      await this.fs.promises.access(this.__path, accessMode);
 
      return new NodePermissionStatus(mode, 'granted');
    } catch (error) {
      // If access check fails, permission is denied
      return new NodePermissionStatus(mode, 'denied');
    }
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle/remove
   */
  public async remove({ recursive }: { recursive?: boolean } = { recursive: false }): Promise<void> {
    throw new Error('Not implemented');
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle/requestPermission
   */
  public requestPermission(
    fileSystemHandlePermissionDescriptor: FileSystemHandlePermissionDescriptor,
  ): NodePermissionStatus {
    throw new Error('Not implemented');
  }
}