or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-braces

Bash-like brace expansion library for JavaScript with complete Bash 4.3 specification support

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/braces@3.0.x

To install, run

npx @tessl/cli install tessl/npm-braces@3.0.0

index.mddocs/

Braces

Braces is a JavaScript library that provides Bash-like brace expansion functionality. It can expand brace patterns into arrays of strings or compile them into optimized regex-compatible strings for pattern matching. The library supports the complete Bash 4.3 braces specification with enhanced safety features to prevent malicious regex attacks.

Package Information

  • Package Name: braces
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install braces

Core Imports

const braces = require('braces');

ESM import:

import braces from 'braces';

Basic Usage

const braces = require('braces');

// Compile to regex-compatible strings (default behavior)
console.log(braces('{a,b,c}'));
//=> ['(a|b|c)']

console.log(braces('a/{x,y,z}/b'));
//=> ['a/(x|y|z)/b']

// Expand to full arrays
console.log(braces('{a,b,c}', { expand: true }));  
//=> ['a', 'b', 'c']

console.log(braces('a/{x,y,z}/b', { expand: true }));
//=> ['a/x/b', 'a/y/b', 'a/z/b']

// Sequences and ranges
console.log(braces('{1..5}', { expand: true }));
//=> ['1', '2', '3', '4', '5']

console.log(braces('{01..05}', { expand: true }));
//=> ['01', '02', '03', '04', '05']

Architecture

Braces is built around several key components that work together to provide flexible brace expansion:

  • Parser: Converts brace patterns into Abstract Syntax Trees (AST) for manipulation
  • Compiler: Transforms AST into optimized regex-compatible strings for pattern matching
  • Expander: Generates complete arrays of all possible string combinations from patterns
  • Stringify: Reconstructs brace patterns from AST nodes for round-trip processing
  • Safety Layer: Prevents malicious patterns through length limits and range restrictions

The library uses a two-phase approach: parsing creates a structured representation, then compilation or expansion produces the final output based on the requested mode.

Capabilities

Main Function

The primary interface for brace expansion and compilation.

/**
 * Expand the given pattern or create a regex-compatible string
 * @param {string|string[]} input - Brace pattern(s) to process
 * @param {BraceOptions} options - Configuration options
 * @returns {string[]} Array of expanded or compiled strings
 */
function braces(input, options = {});

Parse

Parse brace patterns into an Abstract Syntax Tree for advanced manipulation.

/**
 * Parse brace pattern into AST
 * @param {string} input - Brace pattern to parse
 * @param {BraceOptions} options - Configuration options  
 * @returns {BraceAST} Abstract syntax tree representation
 */
braces.parse(input, options = {});

Stringify

Convert an AST back into a brace pattern string.

/**
 * Creates a braces string from an AST or AST node
 * @param {string|BraceAST} input - Brace pattern or AST
 * @param {BraceOptions} options - Configuration options
 * @returns {string} Reconstructed brace pattern string
 */
braces.stringify(input, options = {});

Compile

Compile brace patterns into regex-compatible, optimized strings.

/**
 * Compiles a brace pattern into a regex-compatible, optimized string
 * @param {string|BraceAST} input - Brace pattern or AST
 * @param {BraceOptions} options - Configuration options  
 * @returns {string[]} Array of regex-compatible strings
 */
braces.compile(input, options = {});

Expand

Expand brace patterns into arrays of all possible string combinations.

/**
 * Expands a brace pattern into an array of strings
 * @param {string|BraceAST} input - Brace pattern or AST
 * @param {BraceOptions} options - Configuration options
 * @returns {string[]} Array of expanded strings
 */
braces.expand(input, options = {});

Create

Lower-level function that processes patterns based on options.

/**
 * Processes a brace pattern and returns either expanded array or optimized regex string
 * @param {string} input - Brace pattern  
 * @param {BraceOptions} options - Configuration options
 * @returns {string[]} Array of processed strings
 */
braces.create(input, options = {});

Types

/**
 * Configuration options for brace processing
 */
interface BraceOptions {
  /** Generate expanded array instead of compiled regex (default: undefined) */
  expand?: boolean;
  /** Maximum input string length (default: 10000) */ 
  maxLength?: number;
  /** Remove duplicates from results (default: undefined) */
  nodupes?: boolean;
  /** Maximum range expansion size (default: 1000) */
  rangeLimit?: number;
  /** Filter out empty strings from results (default: undefined) */
  noempty?: boolean;
  /** Custom transformation function for range values. For non-numeric ranges, 'value' is a character code. For numeric ranges, 'value' is the number. */
  transform?: (value: any, index: number) => any;
  /** Treat patterns as regex quantifiers instead of lists (default: undefined) */
  quantifiers?: boolean;
  /** Preserve escape characters in output (default: undefined) */
  keepEscaping?: boolean;
  /** Preserve quotes in parsed output (default: undefined) */
  keepQuotes?: boolean;
  /** Escape invalid brace patterns (default: undefined) */
  escapeInvalid?: boolean;
  /** Step/increment for ranges */
  step?: number;
  /** Wrap ranges in parentheses (passed to fill-range) */
  wrap?: boolean;
  /** Convert ranges to regex (passed to fill-range) */
  toRegex?: boolean;
  /** Preserve leading zeros in ranges (passed to fill-range) */
  strictZeros?: boolean;
}

/**
 * Abstract Syntax Tree node structure
 */
interface BraceAST {
  /** Node type identifier */
  type: 'root' | 'brace' | 'text' | 'comma' | 'open' | 'close' | 'range';
  /** Original input string (root nodes only) */
  input?: string;
  /** Node value/content */
  value?: string;
  /** Child nodes */
  nodes?: BraceAST[];
  /** Whether node is invalid */
  invalid?: boolean;
  /** Whether node is escaped */
  escaped?: boolean;
}

Pattern Support

Braces supports all standard Bash 4.3 brace expansion patterns:

Lists (Sets): Comma-separated alternatives

braces('{a,b,c}');           // => ['(a|b|c)']
braces('{foo,bar,baz}');     // => ['(foo|bar|baz)']

Sequences (Ranges): Numeric or alphabetic ranges

braces('{1..5}');            // => ['([1-5])']
braces('{a..e}');            // => ['([a-e])']
braces('{01..05}');          // => ['(0[1-5])'] (zero-padded)

Stepped Ranges: Ranges with increments

braces('{2..10..2}');        // => ['(2|4|6|8|10)']
braces('{a..z..3}');         // => ['(a|d|g|j|m|p|s|v|y)']

Nested Patterns: Complex nested brace expressions

braces('a/{x,{1..3},y}/b');  // => ['a/(x|([1-3])|y)/b']

Escaping: Prevent evaluation of special characters

braces('a\\{b,c\\}d');       // => ['a{b,c}d'] (not expanded)

Invalid Patterns: Patterns that don't follow proper brace syntax

braces('{a}');               // => ['{a}'] (single item, not expanded)
braces('{a,b');              // => ['{a,b'] (unclosed brace)
braces('a,b}');              // => ['a,b}'] (unopened brace)

Brace patterns are considered invalid when they:

  • Contain unmatched opening or closing braces
  • Have only a single item within braces
  • Contain syntax errors that prevent proper parsing

Error Handling

  • TypeError: Thrown when input to parse() is not a string
  • SyntaxError: Thrown when input length exceeds maxLength limit
  • RangeError: Thrown when expanded array exceeds rangeLimit during expansion

Usage Examples

File path generation:

const paths = braces('./src/{components,utils,types}/**/*.js', { expand: true });
// => ['./src/components/**/*.js', './src/utils/**/*.js', './src/types/**/*.js']

Regex pattern creation:

const pattern = braces('user-{200..300}/project-{a,b,c}')[0];
// => 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)'
const regex = new RegExp(pattern);

Transform range values:

// For numeric ranges, 'value' is the number
const customRange = braces('{1..5}', {
  expand: true,
  transform: (value) => `item${value}`
});
// => ['item1', 'item2', 'item3', 'item4', 'item5']

// For alpha ranges, 'value' is a character code
const alphaRange = braces('{a..e}', {
  expand: true,
  transform: (code, index) => `${String.fromCharCode(code)}-${index}`
});
// => ['a-0', 'b-1', 'c-2', 'd-3', 'e-4']

Safe processing with limits:

try {
  const result = braces('{1..10000}', { 
    expand: true,
    rangeLimit: 100 
  });
} catch (error) {
  console.log('Range too large:', error.message);
  // Use compile mode instead for large ranges
  const compiled = braces('{1..10000}');
  // => ['([1-9]|[1-9][0-9]{1,3}|10000)']
}