0
# Content and Object Matching
1
2
String containment matching and object key filtering capabilities. These functions extend pattern matching beyond exact string matching to partial matching and object manipulation.
3
4
## Capabilities
5
6
### String Containment Matching
7
8
Test if a pattern matches any part of a string, not just the entire string.
9
10
```javascript { .api }
11
/**
12
* Test if pattern matches any part of a string
13
* @param {String} str - String to search within for pattern matches
14
* @param {String|Array} patterns - Patterns to search for within the string
15
* @param {Object} options - Optional configuration object
16
* @returns {Boolean} True if any pattern matches any part of the string
17
*/
18
nanomatch.contains(str, patterns, options);
19
```
20
21
**Usage Examples:**
22
23
```javascript
24
const nanomatch = require('nanomatch');
25
26
// Basic containment matching
27
console.log(nanomatch.contains('src/components/button.js', 'components'));
28
//=> true
29
30
console.log(nanomatch.contains('src/components/button.js', 'widgets'));
31
//=> false
32
33
// Pattern-based containment
34
console.log(nanomatch.contains('path/to/file.js', '*.js'));
35
//=> true (matches the .js part)
36
37
console.log(nanomatch.contains('very/long/path/file.txt', '**/file.*'));
38
//=> true (matches the file.txt part)
39
40
// Multiple patterns
41
console.log(nanomatch.contains('src/app.component.ts', ['*.js', '*.ts']));
42
//=> true (contains .ts pattern)
43
44
// Wildcard containment
45
console.log(nanomatch.contains('aa/bb/cc', '*b'));
46
//=> true (matches "bb" part)
47
48
console.log(nanomatch.contains('aa/bb/cc', '*d'));
49
//=> false (no part matches *d)
50
51
// Case sensitivity
52
console.log(nanomatch.contains('MyComponent.JS', '*.js'));
53
//=> false
54
55
console.log(nanomatch.contains('MyComponent.JS', '*.js', { nocase: true }));
56
//=> true
57
```
58
59
### Object Key Filtering
60
61
Filter object properties using glob patterns on the property names.
62
63
```javascript { .api }
64
/**
65
* Filter object keys using glob patterns
66
* @param {Object} object - Object with keys to filter using patterns
67
* @param {String|Array} patterns - One or more patterns to match against keys
68
* @param {Object} options - Optional configuration object
69
* @returns {Object} New object containing only keys that match patterns
70
*/
71
nanomatch.matchKeys(object, patterns, options);
72
```
73
74
**Usage Examples:**
75
76
```javascript
77
const nanomatch = require('nanomatch');
78
79
// Basic key filtering
80
const config = {
81
apiUrl: 'https://api.example.com',
82
apiKey: 'secret123',
83
dbHost: 'localhost',
84
dbPort: 5432,
85
logLevel: 'info'
86
};
87
88
console.log(nanomatch.matchKeys(config, 'api*'));
89
//=> { apiUrl: 'https://api.example.com', apiKey: 'secret123' }
90
91
console.log(nanomatch.matchKeys(config, 'db*'));
92
//=> { dbHost: 'localhost', dbPort: 5432 }
93
94
// Multiple patterns
95
console.log(nanomatch.matchKeys(config, ['api*', 'log*']));
96
//=> { apiUrl: 'https://api.example.com', apiKey: 'secret123', logLevel: 'info' }
97
98
// Question mark patterns
99
const data = { a1: 'val1', a2: 'val2', b1: 'val3', ab: 'val4' };
100
console.log(nanomatch.matchKeys(data, 'a?'));
101
//=> { a1: 'val1', a2: 'val2' }
102
103
// Bracket patterns
104
console.log(nanomatch.matchKeys(data, '[ab]*'));
105
//=> { a1: 'val1', a2: 'val2', b1: 'val3', ab: 'val4' }
106
107
// Negation patterns
108
console.log(nanomatch.matchKeys(config, ['*', '!db*']));
109
//=> { apiUrl: 'https://api.example.com', apiKey: 'secret123', logLevel: 'info' }
110
111
// Case insensitive matching
112
const mixedCase = { ApiUrl: 'url', APIKEY: 'key', dbhost: 'host' };
113
console.log(nanomatch.matchKeys(mixedCase, 'api*', { nocase: true }));
114
//=> { ApiUrl: 'url', APIKEY: 'key' }
115
116
// Complex nested objects (only top-level keys are matched)
117
const nested = {
118
user: { name: 'John', email: 'john@example.com' },
119
config: { theme: 'dark', lang: 'en' },
120
temp: 'temporary'
121
};
122
123
console.log(nanomatch.matchKeys(nested, '*er'));
124
//=> { user: { name: 'John', email: 'john@example.com' } }
125
```
126
127
## Advanced Usage Patterns
128
129
### Containment vs Exact Matching
130
131
```javascript
132
const nanomatch = require('nanomatch');
133
134
const filePath = 'src/components/user-profile.component.ts';
135
136
// Exact matching (isMatch) - tests entire string
137
console.log(nanomatch.isMatch(filePath, '*.ts'));
138
//=> false (entire string doesn't match *.ts)
139
140
console.log(nanomatch.isMatch(filePath, '**/*.ts'));
141
//=> true (entire string matches this pattern)
142
143
// Containment matching - tests parts of string
144
console.log(nanomatch.contains(filePath, '*.ts'));
145
//=> true (contains something matching *.ts)
146
147
console.log(nanomatch.contains(filePath, 'user-profile'));
148
//=> true (contains this substring)
149
150
console.log(nanomatch.contains(filePath, 'components'));
151
//=> true (contains this substring)
152
```
153
154
### Object Filtering Patterns
155
156
```javascript
157
const nanomatch = require('nanomatch');
158
159
// Environment variables filtering
160
const env = {
161
NODE_ENV: 'development',
162
API_URL: 'http://localhost:3000',
163
API_KEY: 'dev-key-123',
164
DB_HOST: 'localhost',
165
DB_PORT: '5432',
166
LOG_LEVEL: 'debug'
167
};
168
169
// Get all API-related variables
170
const apiVars = nanomatch.matchKeys(env, 'API_*');
171
//=> { API_URL: 'http://localhost:3000', API_KEY: 'dev-key-123' }
172
173
// Get all database variables
174
const dbVars = nanomatch.matchKeys(env, 'DB_*');
175
//=> { DB_HOST: 'localhost', DB_PORT: '5432' }
176
177
// Get non-API variables
178
const nonApiVars = nanomatch.matchKeys(env, ['*', '!API_*']);
179
//=> { NODE_ENV: 'development', DB_HOST: 'localhost', DB_PORT: '5432', LOG_LEVEL: 'debug' }
180
181
// Package.json script filtering
182
const scripts = {
183
start: 'node server.js',
184
'build:dev': 'webpack --mode development',
185
'build:prod': 'webpack --mode production',
186
'test:unit': 'jest unit',
187
'test:integration': 'jest integration',
188
lint: 'eslint .',
189
'lint:fix': 'eslint . --fix'
190
};
191
192
console.log(nanomatch.matchKeys(scripts, 'build:*'));
193
//=> { 'build:dev': 'webpack --mode development', 'build:prod': 'webpack --mode production' }
194
195
console.log(nanomatch.matchKeys(scripts, 'test:*'));
196
//=> { 'test:unit': 'jest unit', 'test:integration': 'jest integration' }
197
198
console.log(nanomatch.matchKeys(scripts, '*:*'));
199
//=> All keys containing colons
200
```
201
202
## Error Handling and Edge Cases
203
204
```javascript
205
const nanomatch = require('nanomatch');
206
207
// TypeError for non-string input to contains()
208
try {
209
nanomatch.contains(123, '*.js');
210
} catch (error) {
211
console.log(error.message);
212
//=> 'expected a string: "123"'
213
}
214
215
// TypeError for non-object input to matchKeys()
216
try {
217
nanomatch.matchKeys('not-an-object', '*');
218
} catch (error) {
219
console.log(error.message);
220
//=> 'expected the first argument to be an object'
221
}
222
223
// Empty string handling
224
console.log(nanomatch.contains('', ''));
225
//=> false
226
227
console.log(nanomatch.contains('test', ''));
228
//=> false
229
230
// Empty object handling
231
console.log(nanomatch.matchKeys({}, '*'));
232
//=> {}
233
234
// null/undefined values in objects are preserved
235
const objWithNulls = { a: null, b: undefined, c: 'value' };
236
console.log(nanomatch.matchKeys(objWithNulls, '*'));
237
//=> { a: null, b: undefined, c: 'value' }
238
```
239
240
## Performance Notes
241
242
- `contains()` internally uses the same pattern compilation and caching as other nanomatch functions
243
- `matchKeys()` only evaluates patterns against object keys, not values
244
- Both functions benefit from nanomatch's memoization system for repeated patterns
245
- `matchKeys()` creates a new object; it does not modify the original object
246
- For large objects, consider filtering keys first with `Object.keys()` if you only need the key names