Glob Notation
A glob is a notation with two extra powers: the wildcard star * (match all
properties at a level) and the bang ! prefix (negate — exclude the match).
* // the whole objectbilling.* // everything under billing!billing.* // everything except billing's contentsname // just nameGlobs are accepted by Notation#filter() for
filtering data. For working with the patterns themselves — validating,
comparing, combining — use the NotationGlob class.
import { NotationGlob } from 'notation';
const g = new NotationGlob('billing.account.*');g.test('billing.account.id'); // » trueInstance Shape
Section titled “Instance Shape”A NotationGlob exposes its parsed form. Trailing redundant wildcards are
stripped on construction:
const g = NotationGlob.create('!store.address.*');g.glob; // » "!store.address.*"g.absGlob; // » "store.address.*" (negation removed)g.isNegated; // » trueg.notes; // » ["store", "address", "*"]g.parent; // » "store.address"test(notation) checks a concrete notation against the glob; covers(glob)
checks whether this glob can represent another (negation ignored):
NotationGlob.create('*.y').covers('x.y'); // » trueNotationGlob.create('x[*].y').covers('x[*]'); // » falseNormalize
Section titled “Normalize”NotationGlob.normalize(list) removes duplicates and redundant items, resolves
negations, and returns a logically sorted array. This is the heart of how globs
combine.
const globs = ['*', '!id', 'name', 'car.model', '!car.*', 'id', 'name', 'age'];NotationGlob.normalize(globs);// » ['*', '!car.*', '!id', 'car.model']What happened:
idis dropped; its negated twin!idwins (negation always beats the positive when both are present).- The duplicate
nameis removed, thennameandagego too —*already covers every non-negated notation. car.modelsurvives: it’s explicitly listed and a negated glob (!car.*) also matches it, so it’s not redundant.
Restrictive Mode
Section titled “Restrictive Mode”By default a negated glob doesn’t remove an explicitly-listed positive. In restrictive mode, negation wins every match:
NotationGlob.normalize(globs, true);// » ['*', '!car.*', '!id'] (car.model removed)The same restrictive flag is available on
filter() and union().
union(a, b) merges two glob lists optimistically (positive wins over negated
when both are present), then normalizes:
const a = ['*', '!car.model', 'car.brand', '!*.age'];const b = ['car.model', 'user.age', 'user.name'];NotationGlob.union(a, b);// » ['*', '!*.age', 'user.age']!car.model drops because b has the exact positive; car.model is then
redundant under *; user.age stays because !*.age still matches it.
Compare, Sort, Intersect
Section titled “Compare, Sort, Intersect”compare/sort order globs from loose to specific (* < *.y < x.y), with a
negated glob sorting after its positive twin:
NotationGlob.sort(['!prop.*.name', 'prop.*', 'prop.id']);// » ['prop.*', 'prop.id', '!prop.*.name']intersect finds the overlap of two globs — the basis for how negations
propagate during normalization:
NotationGlob.create('x.*').intersect('!*.y'); // » "x.y"NotationGlob.create('x.*').intersect('!*.y', true); // » "!x.y" (restrictive)Detection Helpers
Section titled “Detection Helpers”NotationGlob.isValid('!a.*'); // » trueNotationGlob.hasMagic('a.b'); // » false (no wildcard or negation)NotationGlob.hasMagic('!a.b'); // » trueNotationGlob.toRegExp('a.*'); // » /^a\.[a-z$_][a-z$_\d]*(?:[[.].+|$)/iPutting globs to work on data is covered in Filtering Data, and the rules that keep glob lists valid are in Data Integrity.