CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nanomatch

Fast, minimal glob matcher for node.js with complete Bash 4.3 wildcard support

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

content-matching.mddocs/

Content and Object Matching

String containment matching and object key filtering capabilities. These functions extend pattern matching beyond exact string matching to partial matching and object manipulation.

Capabilities

String Containment Matching

Test if a pattern matches any part of a string, not just the entire string.

/**
 * Test if pattern matches any part of a string
 * @param {String} str - String to search within for pattern matches
 * @param {String|Array} patterns - Patterns to search for within the string
 * @param {Object} options - Optional configuration object
 * @returns {Boolean} True if any pattern matches any part of the string
 */
nanomatch.contains(str, patterns, options);

Usage Examples:

const nanomatch = require('nanomatch');

// Basic containment matching
console.log(nanomatch.contains('src/components/button.js', 'components'));
//=> true

console.log(nanomatch.contains('src/components/button.js', 'widgets'));  
//=> false

// Pattern-based containment
console.log(nanomatch.contains('path/to/file.js', '*.js'));
//=> true (matches the .js part)

console.log(nanomatch.contains('very/long/path/file.txt', '**/file.*'));
//=> true (matches the file.txt part)

// Multiple patterns
console.log(nanomatch.contains('src/app.component.ts', ['*.js', '*.ts']));
//=> true (contains .ts pattern)

// Wildcard containment
console.log(nanomatch.contains('aa/bb/cc', '*b'));
//=> true (matches "bb" part)

console.log(nanomatch.contains('aa/bb/cc', '*d'));
//=> false (no part matches *d)

// Case sensitivity
console.log(nanomatch.contains('MyComponent.JS', '*.js'));
//=> false

console.log(nanomatch.contains('MyComponent.JS', '*.js', { nocase: true }));
//=> true

Object Key Filtering

Filter object properties using glob patterns on the property names.

/**
 * Filter object keys using glob patterns
 * @param {Object} object - Object with keys to filter using patterns
 * @param {String|Array} patterns - One or more patterns to match against keys
 * @param {Object} options - Optional configuration object
 * @returns {Object} New object containing only keys that match patterns
 */
nanomatch.matchKeys(object, patterns, options);

Usage Examples:

const nanomatch = require('nanomatch');

// Basic key filtering
const config = {
  apiUrl: 'https://api.example.com',
  apiKey: 'secret123',
  dbHost: 'localhost',
  dbPort: 5432,
  logLevel: 'info'
};

console.log(nanomatch.matchKeys(config, 'api*'));
//=> { apiUrl: 'https://api.example.com', apiKey: 'secret123' }

console.log(nanomatch.matchKeys(config, 'db*'));
//=> { dbHost: 'localhost', dbPort: 5432 }

// Multiple patterns
console.log(nanomatch.matchKeys(config, ['api*', 'log*']));
//=> { apiUrl: 'https://api.example.com', apiKey: 'secret123', logLevel: 'info' }

// Question mark patterns
const data = { a1: 'val1', a2: 'val2', b1: 'val3', ab: 'val4' };
console.log(nanomatch.matchKeys(data, 'a?'));
//=> { a1: 'val1', a2: 'val2' }

// Bracket patterns
console.log(nanomatch.matchKeys(data, '[ab]*'));
//=> { a1: 'val1', a2: 'val2', b1: 'val3', ab: 'val4' }

// Negation patterns
console.log(nanomatch.matchKeys(config, ['*', '!db*']));
//=> { apiUrl: 'https://api.example.com', apiKey: 'secret123', logLevel: 'info' }

// Case insensitive matching
const mixedCase = { ApiUrl: 'url', APIKEY: 'key', dbhost: 'host' };
console.log(nanomatch.matchKeys(mixedCase, 'api*', { nocase: true }));
//=> { ApiUrl: 'url', APIKEY: 'key' }

// Complex nested objects (only top-level keys are matched)
const nested = {
  user: { name: 'John', email: 'john@example.com' },
  config: { theme: 'dark', lang: 'en' },
  temp: 'temporary'
};

console.log(nanomatch.matchKeys(nested, '*er'));
//=> { user: { name: 'John', email: 'john@example.com' } }

Advanced Usage Patterns

Containment vs Exact Matching

const nanomatch = require('nanomatch');

const filePath = 'src/components/user-profile.component.ts';

// Exact matching (isMatch) - tests entire string
console.log(nanomatch.isMatch(filePath, '*.ts'));
//=> false (entire string doesn't match *.ts)

console.log(nanomatch.isMatch(filePath, '**/*.ts'));
//=> true (entire string matches this pattern)

// Containment matching - tests parts of string
console.log(nanomatch.contains(filePath, '*.ts'));
//=> true (contains something matching *.ts)

console.log(nanomatch.contains(filePath, 'user-profile'));
//=> true (contains this substring)

console.log(nanomatch.contains(filePath, 'components'));
//=> true (contains this substring)

Object Filtering Patterns

const nanomatch = require('nanomatch');

// Environment variables filtering
const env = {
  NODE_ENV: 'development',
  API_URL: 'http://localhost:3000',
  API_KEY: 'dev-key-123',
  DB_HOST: 'localhost',
  DB_PORT: '5432',
  LOG_LEVEL: 'debug'
};

// Get all API-related variables
const apiVars = nanomatch.matchKeys(env, 'API_*');
//=> { API_URL: 'http://localhost:3000', API_KEY: 'dev-key-123' }

// Get all database variables
const dbVars = nanomatch.matchKeys(env, 'DB_*');
//=> { DB_HOST: 'localhost', DB_PORT: '5432' }

// Get non-API variables
const nonApiVars = nanomatch.matchKeys(env, ['*', '!API_*']);
//=> { NODE_ENV: 'development', DB_HOST: 'localhost', DB_PORT: '5432', LOG_LEVEL: 'debug' }

// Package.json script filtering
const scripts = {
  start: 'node server.js',
  'build:dev': 'webpack --mode development',
  'build:prod': 'webpack --mode production',
  'test:unit': 'jest unit',
  'test:integration': 'jest integration',
  lint: 'eslint .',
  'lint:fix': 'eslint . --fix'
};

console.log(nanomatch.matchKeys(scripts, 'build:*'));
//=> { 'build:dev': 'webpack --mode development', 'build:prod': 'webpack --mode production' }

console.log(nanomatch.matchKeys(scripts, 'test:*'));
//=> { 'test:unit': 'jest unit', 'test:integration': 'jest integration' }

console.log(nanomatch.matchKeys(scripts, '*:*'));
//=> All keys containing colons

Error Handling and Edge Cases

const nanomatch = require('nanomatch');

// TypeError for non-string input to contains()
try {
  nanomatch.contains(123, '*.js');
} catch (error) {
  console.log(error.message);
  //=> 'expected a string: "123"'
}

// TypeError for non-object input to matchKeys()
try {
  nanomatch.matchKeys('not-an-object', '*');
} catch (error) {
  console.log(error.message);
  //=> 'expected the first argument to be an object'
}

// Empty string handling
console.log(nanomatch.contains('', ''));
//=> false

console.log(nanomatch.contains('test', ''));
//=> false

// Empty object handling
console.log(nanomatch.matchKeys({}, '*'));
//=> {}

// null/undefined values in objects are preserved
const objWithNulls = { a: null, b: undefined, c: 'value' };
console.log(nanomatch.matchKeys(objWithNulls, '*'));
//=> { a: null, b: undefined, c: 'value' }

Performance Notes

  • contains() internally uses the same pattern compilation and caching as other nanomatch functions
  • matchKeys() only evaluates patterns against object keys, not values
  • Both functions benefit from nanomatch's memoization system for repeated patterns
  • matchKeys() creates a new object; it does not modify the original object
  • For large objects, consider filtering keys first with Object.keys() if you only need the key names

docs

collection-operations.md

content-matching.md

core-matching.md

index.md

matcher-creation.md

regex-compilation.md

tile.json