or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

findup-sync

findup-sync is a utility that finds the first file matching a given pattern by recursively searching from a starting directory upward through parent directories until a match is found or the root directory is reached. It uses micromatch for powerful glob pattern matching and integrates with detect-file for enhanced file detection.

Package Information

  • Package Name: findup-sync
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install findup-sync

Core Imports

const findup = require('findup-sync');

Note: This package is CommonJS only and does not provide native ES module support.

Basic Usage

const findup = require('findup-sync');

// Find package.json starting from current directory
const packagePath = findup('package.json');

// Find config files with glob patterns
const configPath = findup('*.config.{js,json}');

// Start searching from a specific directory
const filepath = findup('README.md', { cwd: '/some/project/path' });

// Case-insensitive search
const caseInsensitivePath = findup('readme.*', { nocase: true });

// Search for multiple patterns (returns first match)
const multiPattern = findup(['gulpfile.js', 'Gulpfile.js', 'gulpfile.babel.js']);

Algorithm

The package implements an upward directory traversal algorithm:

  1. Starting Point: Begins search from the specified cwd directory (or current working directory if not specified)
  2. Pattern Matching: For each directory in the search path:
    • If pattern is a glob: Uses micromatch to test all files in the directory
    • If pattern is a literal path: Uses detect-file to check for exact file existence
  3. Directory Traversal: If no match found, moves to parent directory and repeats
  4. Termination: Stops when a match is found or when the root directory is reached
  5. Multiple Patterns: When an array is provided, tests each pattern in order and returns the first match

Capabilities

File Pattern Matching

Finds the first file matching a given pattern by searching upward through the directory tree from a starting point.

/**
 * Find the first file matching a given pattern in the current directory or the nearest ancestor directory.
 * @param {string|string[]} patterns - Glob pattern(s) or file path(s) to match against
 * @param {object} [options] - Options to pass to micromatch and configure search behavior
 * @returns {string|null} Returns the absolute path to the first matching file, or null if no match found
 * @throws {TypeError} When the first argument is not a string or array
 */
module.exports = function(patterns, options);

Parameters:

  • patterns (string|string[]): Glob pattern(s) or file path(s) to match against. Can be:

    • Single string pattern: 'package.json'
    • Glob pattern: '*.config.js' or '**/package.json'
    • Array of patterns: ['gulpfile.js', 'Gulpfile.js']
    • Exact file paths: 'config/app.json'
  • options (object, optional): Configuration options

    • cwd (string): Starting directory for search (defaults to process.cwd())
    • nocase (boolean): Case-insensitive matching when true
    • matchBase (boolean): Match basename of files when true
    • Additional micromatch options are supported

Return Value:

  • Returns the absolute path (string) to the first matching file
  • Returns null if no matching file is found
  • The search walks up the directory tree from the starting directory until a match is found or the root directory is reached

Error Handling:

  • Throws TypeError if the first argument is not a string or array
  • Safely handles inaccessible directories (uses try-catch on fs.readdirSync, continues search)
  • Returns null for invalid patterns or when no files match
  • Handles filesystem permission errors gracefully by ignoring unreadable directories
  • No errors thrown for non-existent directories in the traversal path

Usage Examples:

const findup = require('findup-sync');

// Basic file search
const pkg = findup('package.json');
// Returns: "/path/to/project/package.json" or null

// Glob patterns
const config = findup('*.config.{js,json}');
// Matches: webpack.config.js, babel.config.json, etc.

// Multiple patterns (first match wins)
const gulp = findup(['gulpfile.js', 'Gulpfile.js', 'gulpfile.babel.js']);

// Custom starting directory
const readme = findup('README.*', { cwd: '/some/project/deep/nested/dir' });

// Case-insensitive search
const license = findup('license*', { nocase: true });
// Matches: LICENSE, License.txt, license.md

// Complex glob patterns
const nested = findup('**/test/fixtures/*.json');

// Exact path matching
const specific = findup('config/database.yml', { cwd: '/app/src' });

// Match basename only
const base = findup('package.json', { matchBase: true });
// Finds package.json at any depth

// Tilde expansion (home directory)
const home = findup('.*rc', { cwd: '~' });

Advanced Usage Patterns

Working with Build Tools

// Find configuration files for build tools
const webpackConfig = findup(['webpack.config.js', 'webpack.config.babel.js']);
const gulpfile = findup(['gulpfile.js', 'gulpfile.babel.js', 'Gulpfile.js']);
const gruntfile = findup(['Gruntfile.js', 'gruntfile.js']);

// Find project root by looking for package.json
const projectRoot = findup('package.json');
const rootDir = projectRoot ? require('path').dirname(projectRoot) : null;

Configuration File Discovery

// Look for various config formats
const eslintConfig = findup([
  '.eslintrc.js',
  '.eslintrc.json',
  '.eslintrc.yml',
  '.eslintrc.yaml'
]);

// Find test configuration
const jestConfig = findup(['jest.config.js', 'jest.config.json']);
const mochaOpts = findup(['.mocharc.json', '.mocharc.yml', 'mocha.opts']);

Monorepo and Nested Project Handling

// Start from deep nested directory, find nearest package.json
const nearestPkg = findup('package.json', { 
  cwd: '/monorepo/packages/sub-package/src/components' 
});

// Find workspace root (usually has workspaces field in package.json)
const workspaceRoot = findup('lerna.json') || findup('pnpm-workspace.yaml');