Socket
Socket
Sign inDemoInstall

escalade

Package Overview
Dependencies
0
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    escalade

A tiny (186B to 214B) and fast utility to ascend parent directories


Version published
Weekly downloads
39M
decreased by-7.93%
Maintainers
1
Install size
11.5 kB
Created
Weekly downloads
 

Package description

What is escalade?

The escalade npm package is a utility designed to simplify the process of ascending file system directories and performing actions based on the presence of specific files or directories. It is particularly useful for tasks such as configuration file discovery, project root identification, and more, by moving up from a given directory until a specified condition is met.

What are escalade's main functionalities?

Finding a specific file in parent directories

This feature allows you to start from a specific directory and move up the directory tree until a file named 'target-file.txt' is found. Once found, you can return a specific path or action based on the discovery.

const escalade = require('escalade');

escalade('/start/path', (dir, names) => {
  if (names.includes('target-file.txt')) {
    return 'path/to/return';
  }
});

Custom condition for directory traversal

This demonstrates how escalade can be used to ascend directories based on a custom condition, such as finding a configuration file with a specific extension. This is useful for dynamically locating project or application configuration files.

const escalade = require('escalade');

escalade('/start/path', (dir, names) => {
  if (names.some(name => name.endsWith('.config.js'))) {
    return 'path/to/specific/config';
  }
});

Other packages similar to escalade

Readme

Source

escalade CI codecov

A tiny (186B to 214B) and fast utility to ascend parent directories

With escalade, you can scale parent directories until you've found what you're looking for.
Given an input file or directory, escalade will continue executing your callback function until either:

  1. the callback returns a truthy value
  2. escalade has reached the root directory (process.cwd())

Important:
Please note that escalade will never traverse beyond the root directory.
Additionally, escalade only deals with direct ancestry – it will not dive into parents' sibling directories.

Install

$ npm install --save escalade

Modes

There are two "versions" of escalade available:

"async"

Node.js: >= 8.x
Size (gzip): 214 bytes
Availability: CommonJS, ES Module

This is the primary/default mode. It makes use of async/await and util.promisify.

"sync"

Node.js: >= 6.x
Size (gzip): 186 bytes
Availability: CommonJS, ES Module

This is the opt-in mode, ideal for scenarios where async usage cannot be supported.

Usage

Example Structure

Assume process.cwd() is /Users/lukeed/oss/escalade

/Users/lukeed
  └── oss
    ├── license
    └── escalade
      ├── package.json
      └── test
        └── fixtures
          ├── index.js
          └── foobar
            └── demo.js

Example Usage

//~> demo.js
import { join } from 'path';
import escalade from 'escalade';

const input = join(__dirname, 'demo.js');
// or: const input = __dirname;

const pkg = await escalade(input, (dir, names) => {
  console.log('~> dir:', dir);
  console.log('~> names:', names);
  console.log('---');

  if (names.includes('package.json')) {
    // will be resolved into absolute
    return 'package.json';
  }
});

//~> dir: /Users/lukeed/oss/escalade/test/fixtures/foobar
//~> names: ['demo.js']
//---
//~> dir: /Users/lukeed/oss/escalade/test/fixtures
//~> names: ['index.js', 'foobar']
//---
//~> dir: /Users/lukeed/oss/escalade/test
//~> names: ['fixtures']
//---
//~> dir: /Users/lukeed/oss/escalade
//~> names: ['package.json', 'test']
//---

console.log(pkg);
//=> /Users/lukeed/oss/escalade/package.json

// Now search for "license"
// ~> Will never leave "/Users/lukeed/oss/escalade" directory
const license = await escalade(input, (dir, names) => {
  console.log('~> dir:', dir);
  return names.includes('license') && 'license';
});

//~> dir: /Users/lukeed/oss/escalade/test/fixtures/foobar
//~> dir: /Users/lukeed/oss/escalade/test/fixtures
//~> dir: /Users/lukeed/oss/escalade/test
//~> dir: /Users/lukeed/oss/escalade

console.log(license);
//=> undefined

Note: To run the above example with "sync" mode, import from escalade/sync and remove the await keyword.

API

escalade(input, callback)

Returns: string|void or Promise<string|void>

When your callback locates a file, escalade will resolve/return with an absolute path.
If your callback was never satisfied, then escalade will resolve/return with nothing (undefined).

Important:
The sync and async versions share the same API.
The only difference is that sync is not Promise-based.

input

Type: string

The path from which to start ascending.

This may be a file or a directory path.
However, when input is a file, escalade will begin with its parent directory.

Important: Unless given an absolute path, input will be resolved from process.cwd() location.

callback

Type: Function

The callback to execute for each ancestry level. It always is given two arguments:

  1. dir - an absolute path of the current parent directory
  2. names - a list (string[]) of contents relative to the dir parent

Note: The names list can contain names of files and directories.

When your callback returns a falsey value, then escalade will continue with dir's parent directory, re-invoking your callback with new argument values.

When your callback returns a string, then escalade stops iteration immediately.
If the string is an absolute path, then it's left as is. Otherwise, the string is resolved into an absolute path from the dir that housed the satisfying condition.

Important: Your callback can be a Promise/AsyncFunction when using the "async" version of escalade.

Benchmarks

Running on Node.js v10.13.0

# Load Time
  find-up:        3.948ms
  escalade:       0.493ms
  escalade/sync:  0.327ms

# Levels: 6 (target = "foo.txt"):
  find-up              x 30,614 ops/sec ±7.80% (46 runs sampled)
  escalade             x 46,814 ops/sec ±3.38% (74 runs sampled)
  escalade/sync        x  9,319 ops/sec ±0.53% (89 runs sampled)

# Levels: 12 (target = "package.json"):
  find-up              x 26,421 ops/sec ±16.54% (32 runs sampled)
  escalade             x 49,618 ops/sec ±2.82% (80 runs sampled)
  escalade/sync        x  4,721 ops/sec ±0.51% (92 runs sampled)

# Levels: 14 (target = "missing123.txt"):
  find-up              x 30,254 ops/sec ±15.38% (66 runs sampled)
  escalade             x 50,126 ops/sec ±2.45% (84 runs sampled)
  escalade/sync        x  4,173 ops/sec ±0.45% (93 runs sampled)
  • premove - A tiny (247B) utility to remove items recursively
  • totalist - A tiny (195B to 224B) utility to recursively list all (total) files in a directory
  • mk-dirs - A tiny (420B) utility to make a directory and its parents, recursively

License

MIT © Luke Edwards

Keywords

FAQs

Last updated on 19 Jun 2020

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc