CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-mem-fs-editor

File edition helpers working on top of mem-fs

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

file-management.mddocs/

File Management

File management operations including moving, deleting, and bulk operations with glob pattern support for reorganizing and cleaning up file structures.

Capabilities

Move Files

Move files or directories by copying to the destination and deleting the source, with support for pattern matching and options.

/**
 * Move file or directory (copy + delete)
 * @param from - Source path
 * @param to - Destination path  
 * @param options - Copy options applied during move
 */
function move(from: string, to: string, options?: CopyOptions): void;

interface CopyOptions {
  /** Disable glob pattern matching (default: false) */
  noGlob?: boolean;
  /** Options passed to glob library */
  globOptions?: GlobOptions;
  /** Don't throw error if no files match pattern (default: false) */
  ignoreNoMatch?: boolean;
  /** Base path for relative source paths */
  fromBasePath?: string;
  /** Transform destination paths */
  processDestinationPath?: (path: string) => string;
  /** Append to destination files instead of overwriting */
  append?: boolean;
  /** Process file contents during move */
  process?: (contents: string | Buffer, filepath: string, destination: string) => string | Buffer;
}

Usage Examples:

import { create as createMemFs } from "mem-fs";
import { create as createEditor } from "mem-fs-editor";

const store = createMemFs();
const fs = createEditor(store);

// Move single file
fs.move("old-location/file.txt", "new-location/file.txt");

// Move and rename
fs.move("temp/draft.md", "docs/final.md");

// Move with directory creation
fs.move("src/components/Button.tsx", "src/ui/components/Button.tsx");

// Move with path transformation
fs.move("legacy/old-config.json", "config/app-config.json", {
  process: (contents) => {
    // Update config format during move
    const config = JSON.parse(contents.toString());
    return JSON.stringify({
      version: "2.0",
      ...config,
      migrated: true
    }, null, 2);
  }
});

Delete Files

Delete files using glob patterns with support for batch operations and selective deletion.

/**
 * Delete files using glob patterns
 * @param paths - File paths or glob patterns to delete
 * @param options - Deletion configuration options
 */
function delete(paths: string | string[], options?: DeleteOptions): void;

interface DeleteOptions {
  /** Options passed to glob library for pattern matching */
  globOptions?: GlobOptions;
}

interface GlobOptions {
  /** Exclude directories from results */
  nodir?: boolean;
  /** Patterns to ignore during deletion */
  ignore?: string | string[];
  /** Additional glob options */
  [key: string]: any;
}

Usage Examples:

// Delete single file
fs.delete("temp/cache.txt");

// Delete multiple specific files
fs.delete(["temp/file1.txt", "temp/file2.txt"]);

// Delete with glob pattern
fs.delete("temp/**/*.tmp");

// Delete all files in directory
fs.delete("logs/*");

// Delete with exclusions
fs.delete("dist/**/*", {
  globOptions: {
    ignore: ["dist/important/**", "dist/*.config.js"]
  }
});

// Delete only files, not directories
fs.delete("cleanup/**/*", {
  globOptions: {
    nodir: true
  }
});

Advanced File Management Patterns

Bulk File Operations

// Reorganize project structure
const moveOperations = [
  { from: "old-src/**/*.js", to: "src/js/" },
  { from: "old-styles/**/*.css", to: "src/styles/" },
  { from: "old-assets/**/*.{png,jpg}", to: "src/assets/images/" }
];

moveOperations.forEach(({ from, to }) => {
  fs.move(from, to, {
    processDestinationPath: (path) => {
      // Maintain filename, change directory structure
      const filename = path.split("/").pop();
      return `${to}${filename}`;
    }
  });
});

// Clean up after reorganization
fs.delete(["old-src/**/*", "old-styles/**/*", "old-assets/**/*"]);

Conditional File Management

// Move files based on content
fs.copy("mixed/**/*.js", "temp/"); // Copy to analyze first

// Process each file and move based on content
const filesToMove = fs.dump("temp/");
Object.keys(filesToMove).forEach(filepath => {
  const contents = fs.read(filepath);
  
  if (contents.includes("import React")) {
    fs.move(filepath, `src/components/${filepath.split("/").pop()}`);
  } else if (contents.includes("export default")) {
    fs.move(filepath, `src/utils/${filepath.split("/").pop()}`);
  } else {
    fs.move(filepath, `src/misc/${filepath.split("/").pop()}`);
  }
});

// Clean up temp directory
fs.delete("temp/**/*");

Safe File Operations

// Create backup before moving important files
fs.copy("config/**/*", "backup/config/");
fs.move("config/production.json", "config/prod.config.json");

// Move with validation
const moveWithValidation = (from, to) => {
  if (fs.exists(from)) {
    const contents = fs.read(from);
    if (contents && contents.length > 0) {
      fs.move(from, to);
      console.log(`Moved ${from} to ${to}`);
    } else {
      console.warn(`Skipping empty file: ${from}`);
    }
  } else {
    console.warn(`Source file not found: ${from}`);
  }
};

moveWithValidation("data/temp.json", "data/processed.json");

File Cleanup Patterns

// Clean up generated files
fs.delete([
  "**/*.tmp",
  "**/.DS_Store", 
  "**/Thumbs.db",
  "**/*.log",
  "**/node_modules/.cache/**/*"
]);

// Clean up by file age (using custom logic)
const oldFiles = fs.dump();
Object.keys(oldFiles).forEach(filepath => {
  // Custom logic for old file detection would go here
  if (filepath.includes("temp-") && filepath.includes("2023")) {
    fs.delete(filepath);
  }
});

// Clean up empty directories (directories without files)
fs.delete("**/*/", {
  globOptions: {
    // This would need custom implementation as mem-fs-editor 
    // doesn't directly support empty directory detection
  }
});

Batch Rename Operations

// Rename files with pattern
const renamePattern = (oldPath, newPattern) => {
  const filename = oldPath.split("/").pop();
  const directory = oldPath.substring(0, oldPath.lastIndexOf("/"));
  const newFilename = filename.replace(/old-prefix-/, newPattern);
  return `${directory}/${newFilename}`;
};

// Apply rename pattern
const filesToRename = fs.dump("src/components/");
Object.keys(filesToRename).forEach(filepath => {
  if (filepath.includes("old-prefix-")) {
    const newPath = renamePattern(filepath, "new-prefix-");
    fs.move(filepath, newPath);
  }
});

// Convert file extensions during move
fs.move("typescript/**/*.ts", "javascript/", {
  processDestinationPath: (path) => {
    return path.replace(/\.ts$/, ".js").replace("typescript/", "javascript/");
  },
  process: (contents) => {
    // Basic TypeScript to JavaScript conversion
    return contents
      .toString()
      .replace(/: \w+/g, "")  // Remove type annotations
      .replace(/interface \w+.*?{.*?}/gs, ""); // Remove interfaces
  }
});

Error Handling

// Safe delete with error handling
const safeDelete = (patterns) => {
  try {
    fs.delete(patterns, { globOptions: { nodir: true } });
    console.log(`Deleted files matching: ${patterns}`);
  } catch (error) {
    if (error.message.includes("no files found")) {
      console.log(`No files found for pattern: ${patterns}`);
    } else {
      console.error(`Delete failed: ${error.message}`);
    }
  }
};

safeDelete("temp/**/*.tmp");

// Safe move with existence check
const safeMove = (from, to) => {
  if (fs.exists(from)) {
    try {
      fs.move(from, to);
      console.log(`Moved ${from} to ${to}`);
    } catch (error) {
      console.error(`Failed to move ${from} to ${to}: ${error.message}`);
    }
  } else {
    console.warn(`Source file does not exist: ${from}`);
  }
};

safeMove("old/location.txt", "new/location.txt");

// Bulk operation with error collection
const errors = [];
const moveOperations = [
  { from: "src/old1.js", to: "dist/new1.js" },
  { from: "src/old2.js", to: "dist/new2.js" }
];

moveOperations.forEach(({ from, to }) => {
  try {
    fs.move(from, to);
  } catch (error) {
    errors.push({ operation: "move", from, to, error: error.message });
  }
});

if (errors.length > 0) {
  console.error("Some operations failed:", errors);
}

docs

commit-pipeline.md

file-copy.md

file-management.md

file-reading.md

file-writing.md

index.md

state-management.md

template-processing.md

transform.md

tile.json